阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

Oracle多用户对一个表进行并发插入数据行操作

188次阅读
没有评论

共计 3994 个字符,预计需要花费 10 分钟才能阅读完成。

Oracle 数据库支持多用户间同时对同一个表进行操作,但是数据不一定同步,因为 Oracle 数据库是支持脏数据的,比如 A 用户删除了表的数据但没有提交,B 用户也能查询访问到,如果要避免这种情况只能加锁,A 用户在操作表时先进行 select * from table_name for update, 这是,如果 B 用户再查询时只会等待 A 用户提交完成后才能查询到数据,如果 A 不提交,B 用户只能在等待。

1. 问题 1 多用户对一个表同时进行增,删,改,查等操作的情况

多用户操作的影响主要是会锁定记录,oracle 数据库提供行级锁,也就是说用户操作数据时,oracle 为记录行加锁。当然,如果用户一次性操作的数据过多,oracle 的锁资源过大,或者锁定数据长时间没有释放(例如几百万条记录更新移植没有提交)。oracle 的资源不够,行锁会升级为表锁。至于性能,仍然跟锁定的资源大小有关系。

多用户操作的解决方法:
一次更新量不要太大,记得及时提交结果,养成 sql 语句后面及时、立即 commit 或者 rollback 的习惯。否则待弹出提示界面后,等待用户操作确认的长时间间隔,会导致提交或回滚不及时。
多人操作表是有加锁的。也就是表是共享的,行是独占的。

你正在操作的行别人只能查,不能一起做修改的操作。你 commit 或 rollback 之后就会释放锁别人就可以操作了。
oracle 并发可以解决这个问题,只要在增、删、改时记得及时 commit 或 rollback 就行了.

下面对多用户并发修改某一个行进行分析。

首先你要了解什么叫做“事务 transcation”:一个事务包含一个或多个 DML 语句,是逻辑管理的工作单元(原子单元)。

注意:其中 Commit, Rollback 是显示的提交事务,而 DDL 语句是隐式的提交事务的。DDL 语句的操作是没有办法回滚的。

当用户对数据进行修改时(DML 操作),oracle 会给数据分配两个 锁,一个是行排他锁 另一个是表共享锁

行排他锁:如果 A 用户对某个表的某一行进行修改时,会把该行分配一个”行排他锁“

这样 B 用户就只能查看 不能修改了。但是 B 用户看到的数据确实老数据,那是因为 A 用户还没有结束该事务,换句话说 A 用户拿到了修改该行的所有权,但是怎么修改,修改之后会不会反悔 这些都是在 A 提交该事务之前的  仅属于他个人的事情

而为了保证所有用户所看到数据的一致性,在 A 用户 提交事务之前 大家看到的数据都是 老数据

举个例子:

1. 最开始 谁也没要修改的时候,数据是这样的:

SQL> select empno , ename , sal from emp where empno= 7900;

    EMPNO ENAME            SAL

———- ———- ———-

      7900 JAMES            950

2. A 用户进行修改了,她就拿到了 这行的锁:

SQL> update emp set sal=6000 where empno=7900;

1 row updated.

SQL> select empno , ename , sal from emp where empno= 7900;

    EMPNO ENAME            SAL

———- ———- ———-

      7900 JAMES            6000

现在只有 A 用户能够查看到,修改后的数据。

3. B 用户进行查看:

SQL> select empno , ename , sal from emp where empno= 7900;

    EMPNO ENAME            SAL

———- ———- ———

      7900 JAMES            950

4. B 用户进行修改:

SQL> update emp set sal=6000 where empno=7900;

……… 没有任何动静,因为该会话在等待 A 用户的提交。过了十分钟后,A 用户提交了 那么 B 立刻就抢到了这把锁。

”如果多个用户同时修改同一客户记录, 而且先后提交修改,Oracle 怎样保证该客户记录“就像按抢答器一样,就看是谁先得到这把”锁“

2 问题 2 多用户同时对一个表进行增加操作情况

此时是不是要等一个增加完之后另一个才可以执行增加操作?

一个用户加数据,如果加完数据立即做事务处理,另一个用户就不用太久等待,甚至可能没有感觉。

再如果一个用户加数据加锁后不做事务处理,那另一个用户就会一直等待,直到第一个用户 commit 后才可以执行第二个用户的操作。

1 oracle 的数据模式是:用户建在表空间上,表建在用户上
2 一个用户的表就象自己的私有财产一样,没有自己或管理员授权别的用户是不能查询或修改的;
3 对于不同用户下的同名表,都是独立的数据对象,如 user1.table1 和 user2.table1 是相互独立的,用户分别操作自己的表是不影响其他用户的;
4 对于同一用户下的同一个表,所有有权限的用户对其进行数据操作时,是会相互影响的,如对 user1.table1 来说,user1 修改了它的一行,user2又对该表的该行进行了修改,那么该表的该行的实际内容是在 user1修改后基础上 user2 修改的结果(注意,所有修改以最后成功提交修改请求的用户的内容为准),多个用户对同一个用户下的同一个表的同时修改和锁定,会造成锁等待。

C# 使用实物的 demo

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;
using System.Data;
using Oracle.DataAccess.Client;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Diagnostics;
using System.Data.Common;
using System.Collections;
namespace DB_Server
{
 
    #region // 操作 Oracle 数据库
    public class OracleDBService
    {
        public OracleDBService(string ConnectionString)
        {
            OracleConStr = ConnectionString;         
        }     
        #region// 连接数据库所需变量及方法 
        private string OracleConStr = “”;
        private OracleConnection conn;// 创建 sql 连接
        private OracleCommand com;// 创建 sql 命令对象
        private OracleDataReader dr;// 创建 sql 数据阅读器
        private OracleDataAdapter sdr;// 创建 sql 适配器
        private DataSet ds;// 创建数据集
       
 
        /// <summary>
        /// 创建数据库连接并打开
        /// </summary>
        public void open()
        {
            // 创建连接
            conn = new OracleConnection(OracleConStr);
            if (conn.State == ConnectionState.Closed)
            {
                conn.Open();
            }
            else if (conn.State == ConnectionState.Broken)
            {
                conn.Close();
                conn.Open();
            }       
        }
        #region// 事务操作数据库
        /// <summary>
        /// 提交一组(多条)SQL 语句操作数据库
        /// </summary>
        /// <param name=”commandStringList”>SQL 列表 </param>
        /// <returns> 执行结果 </returns>
        public int UpdateBatchCommand(ArrayList commandStringList)
        {
            open();
            OracleTransaction m_OraTrans = conn.BeginTransaction();// 创建事务对象
            com = new OracleCommand();
            com.Connection = conn;
            string tmpStr = “”;
            int influenceRowCount = 0;
            try
            {
                foreach (string commandString in commandStringList)
                {
                    tmpStr = commandString;
                    com.CommandText = tmpStr;
                    influenceRowCount += com.ExecuteNonQuery();
                }
                m_OraTrans.Commit();
                return influenceRowCount;
            }
            catch (OracleException ex)
            {
                m_OraTrans.Rollback();
                throw ex;
            }
        }
        #endregion

正文完
星哥玩云-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2022-01-22发表,共计3994字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中