zoukankan      html  css  js  c++  java
  • mysql 多个select需要放入一个事务吗?

    第一次写博客,还请大家多多支持微笑



    今天同事问了个问题:在多个select的时候,用不用放入同一个事务?

    首先先看个例子:

    1. public class JDBCClient {  
    2.   
    3.     public static void main(String[] args) {  
    4.         Connection conn = null;  
    5.         try {  
    6.               
    7.             Class.forName("com.mysql.jdbc.Driver");  
    8.             conn = DriverManager.getConnection("jdbc:mysql://localhost/test","root","123456");  
    9.               
    10.             if(conn != null) {  
    11.                 //将本次会话的事务隔离级别设置为TRANSACTION_READ_COMMITTED,mysql默认的是REPEATABLE_READ  
    12.                 conn.setTransactionIsolation(2);  
    13.                 //关闭事务的自动提交  
    14.                 conn.setAutoCommit(false);  
    15.                   
    16.                 PreparedStatement ps = conn.prepareStatement("select student_no from student where student_id = 1 ");  
    17.                 ResultSet rs = ps.executeQuery();  
    18.                 while(rs.next()) {  
    19.                     System.out.println(rs.getString(1));  
    20.                 }  
    21.                   
    22.                 //设置断点,并将数据库中执行 update student set student_no = '新的值' where student_id = 1;然后继续执行  
    23.                 System.out.println("-----------");  
    24.                 rs = ps.executeQuery();  
    25.                 while(rs.next()) {  
    26.                     //这里打印出新赋值的值  
    27.                     System.out.println(rs.getString(1));  
    28.                 }  
    29.                                   
    30.                 //提交事务  
    31.                 //conn.commit();  
    32.             }  
    33.         } catch (Exception e) {  
    34.             e.printStackTrace();  
    35.             if(conn != null) {  
    36.                 try {  
    37.                     conn.rollback();  
    38.                 } catch (SQLException e1) {  
    39.                     e1.printStackTrace();  
    40.                 }  
    41.             }  
    42.         }  
    43.     }  
    44.     //注:如果应用mysql默认的事务隔离级别,则两次打印出的内容一致;  
    45. }  

    个人觉得多个select时,不用放入一个事务,select查询本身不需要事务提交。而如果在修改数据时,不提交事务,则会修改失败。
    select只是用来进行查询操作,不需要事务回滚,因为select不会对数据库的产生持久化的修改,没有必要在数据发生不一致的时候进行回滚。如果要防止数据的不一致情况,可以通过修改事务的隔离级别实现。

    事务:

    事务的四大特性 (ACID)
           1、原子性(Atomicity) 事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。
           2、一致性(Consistency)事务前后数据的完整性必须保持一致。
           3、隔离性(Isolation)多个用户并发访问数据库时,一个用户的事务不能被其它用户的事务所干扰,多个并发事务之间的数据要相互隔离。
           4、持久性(Durability)一个事务一旦被提交,它对数据库中的数据改变就是永久性的。

    事务的隔离级别:
           多个线程开启各自的事务操作数据库中数据时,数据库系统要负责隔离操作,以保证各个线程在获取数据时的准确性。也就是说,隔离级别就是对对事务并发控制的等级。如果事务不考虑隔离性会引发以下问题:
          (1)脏读:
           指一个事务读取了另外一个事务未提交的数据。比如 A 向 B 购买商品,如果 B 的事务隔离级别为最低的 read uncommitted,那么当 A 执行了 update account set money=money+100 where name='B';以后并没有提交数据的时候,B 进行了 select money from account where name='B';查询账户的操作,由于 B 的事务隔离级别最低,所以导致了脏读,读取到了 A 没有提交的数据,当 A 执行了 rollback 回滚命令以后,B 再查询账户,就发现先前增加的 100 元消失了。为了避免脏读,我们可以将事务的隔离级别设置为:read committed。
          (2)不可重复读:
           在一个事务内读取到了表中的某一行数据,多次读取结果不同。不可重复读和脏读的区别是:脏读是读取前一事务未提交的数据,不可重复读是重新读取了前一个事务已提交的数据。比如还是刚才的情景,当 B 将自己的事务隔离级别设置了 read committed 时,可以避免脏读,也就是别人没有提交的数据是读不到的。但是如果 A 将数据提交了,执行了 commit 命令后,B 在这个当前事务内再次查询账户的时候,就发现账户多了 100 元,这种情况看似是符合逻辑的,但是我们这里说到的不可重复读是指在这个当前事务内,不可以发生两次读取操作结果不一致的可能性,我们要保证在一个事务中,我们多次从数据库获取的数据应该是一致的,这样才能保证我们进行数据操作的可靠性。为了避免这个为题,我们可以将数据库的事务隔离级别设置为:repeatable read,这样就保证了在一个事务中,每次读取到数据都是一致的。
          (3)虚读 ( 幻读 )
           在一个事务内读取到了别的事务插入的数据,导致前后读取不一致。和不可重复读的区别是:不可重复读是读取到了别人对表中的某一条记录进行了修改,导致前后读取的数据不一致。  虚读是前后读取到表中的记录总数不一样,读取到了其它事务插入的数据。比如现在有 A 和 B 两个应用程序,他们并发访问了数据库中的某一张表,假设表中有 3 条记录,B 执行查询操作, 第一次查询表得到了 3 条记录。此时 A 对表进行了修改,增加了一条记录,当 B 再次查询表的时候,发现多了一条数据。这种情况就造成了 B 的虚读。但是虚读是不一定每次都发生的,这种情况是不确定的。为了避免虚读,我们可以将事务隔离级别设置为 serializable 如果设置成了这种级别,那么数据库就变成了单线程访问的数据库,导致性能降低很多。

    四种隔离级别及特点:
    隔离级别 是否存在脏读 是否存在不可重复读 是否存在幻读
    Read UnCommit(未提交读) Y Y Y
    Read Commit(提交读) N Y Y
    Repeated Reader(可重复读) N N Y
    Serializable Reader(序列化读) N N N

    这里有个事务隔离级别的例子,写的很好:http://blog.163.com/mr_liuyong/blog/static/1234243762012511105645731/

  • 相关阅读:
    UVA 11174 Stand in a Line,UVA 1436 Counting heaps —— (组合数的好题)
    UVA 1393 Highways,UVA 12075 Counting Triangles —— (组合数,dp)
    【Same Tree】cpp
    【Recover Binary Search Tree】cpp
    【Binary Tree Zigzag Level Order Traversal】cpp
    【Binary Tree Level Order Traversal II 】cpp
    【Binary Tree Level Order Traversal】cpp
    【Binary Tree Post order Traversal】cpp
    【Binary Tree Inorder Traversal】cpp
    【Binary Tree Preorder Traversal】cpp
  • 原文地址:https://www.cnblogs.com/jpfss/p/9151698.html
Copyright © 2011-2022 走看看