zoukankan      html  css  js  c++  java
  • Oracle多用户对一个表进行并发插入数据行操作

     

      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
    View Code

    oracle使用存储过程进行数据更新,可参考下面的博文。

    C#调用Oracle存储过程

    参考文章

    使用oracle数据库,多用户同时对一个表进行增加,删除,修改,查看等操作,会不会有影响

    _DebugOracle多用户同时修改同一记录,怎样保证该客户记录,2017.5.8

    C#使用事务操作ORACLE数据库

  • 相关阅读:
    aircrack-ng 多网卡启动后环境清理
    Docker create image
    预加载(学习一)
    activity+fragment多次切换出现页面空白问题
    万能的Volley
    关于下拉刷新你是否真的非常理解还是只会搬砖?附 Android 实例子源代码文件下载地址380个合集
    如何将Java源代码文件的编码从GBK转为UTF-8?
    如何操作笔记本显得逼格很高?
    跑马灯源代码
    关于java、Android中Math的一些用法
  • 原文地址:https://www.cnblogs.com/arxive/p/9080623.html
Copyright © 2011-2022 走看看