验证mysql的自动提交事务和手动提交事务(java版)
2017-10-25 21:29
375 查看
个人理解的一个事务:是一个Connection一系列的操作过程,如果是两个Connection连接在操作,那就是两个事务。
事务的前提:数据库的存储引擎是innodb。
事务的目的:保证数据的安全性。
事务安全:
1.自动提交事务:每执行一条sql语句,就同步到数据库中。
2.手动提交事务:执行一系列的sql语句后一起同步到数据库中。
事务的四大特性:
A(atomic):原子性,事务中的全部操作是一个整体,要么全部成功,要么全部失败;
C(consistency):一致性:事务开启后,数据表中的数据状态没有变化,因为还没有提交;
I(Isolation):隔离型,多个事务操作是相互隔离,互不影响的;
D(Durability):持久性,事务一旦提交,数据表就发生永久改变.
自动提交事务和手动提交事务的区别:
自动提交事务:
在数据库工具下的测试:
数据库的数据:
自动提交事务执行select查询的结果:
用java代码测试自动提交事务时的测试结果:
执行结果如下:
结果分析:
1.插入之前,第一次执行select查询语句时,查询到的结果是20,与工具中查的结果是一样的。
2.插入后,第二次执行select查询语句时,查询到的结果为21,说明数据可能插入到数据库中。
3.第二次插入时,因为参数是null,所以出现了空指针异常,没有成功插入到数据库中,sql执行出现异常,转到catch{}代码块中。
4.在catch{}代码块中再次查询,查询到的结果为21,说明第一次数据已经插入到数据库中。
5.在finally{}代码块中再次查询,查询的数据还是21,说明最终第一次数据插入到数据库,但是第二次没有成功插入到数据库中。
显示提交事务
在数据库工具下的测试:
手动提交事务执行select查询的结果
用java代码测试手动提交事务时的测试结果:
执行结果如下:
结果分析:
很明显的一点是:显示提交事务时,如果出现异常,那么执行结果和未执行sql语句之前的结果是一样的。
1.插入之前,第一次执行select查询语句时,查询到的结果是21,与工具中查的结果是一样的。
2.插入后,第二次执行select查询语句时,查询到的结果为22,说明这条数据可能插入到数据库中。
3.第二次插入时,因为参数是null,所以出现了空指针异常,没有成功插入到数据库中,sql执行出现异常,转到catch{}代码块中。
4.在catch{}代码块中再次查询,查询到的结果为21,又回到了第一条数据没有插入之前的结果。
5.在finally{}代码块中再次查询,查询的数据还是21,说明第一次的插入最终没有同步到数据库中
那么问题出现了,第一次插入的数据最终没有同步到数据库中,那么第一次插入后查询到的数据条数是22,这是为什么?属于幻读吗?
对于以上结果做以下分析:
1.原子性:以上所有的操作共用一个客户端的Connection对象,因为显示提交事务,所以为了保证数据的原子性,try{}代码块中的所有更新 操作属于不可分割的一部分,要么全部成功,要么全部失败。
2.是否属于幻读的问题:如果单单理解幻读史两次读取数据的行数结果不一样,那么这确实是幻读。但是真正幻读的概念是两次读取数据中间的时间间隔内,有其他的事务(其他的Connection连接)对表中数据进行了更新的操作,导致两次数据不一致的问题。在这个小demo中,始终用的是同一个Connection链接,属于同一个事务,所以不属于幻读。
3.理解第一次插入后查询到的数据条数是22,就要理解事务操作时数据库执行过程,请看下图:
从上图我们知道这个22的出现是因为:第一次插入的数据写入到了日志文件中,当我们在第一次插入后查询数据时,先从数据库表格中查到数据21,再经过日志文件处理,变成22,此时数据库表格中并没有更新。当第二次插入数据失败时,回滚数据,将日志中的记录删除,最终没有将第一次的数据同步到数据库中,所以最终数据库中的记录数还是21.
事务的前提:数据库的存储引擎是innodb。
事务的目的:保证数据的安全性。
事务安全:
1.自动提交事务:每执行一条sql语句,就同步到数据库中。
2.手动提交事务:执行一系列的sql语句后一起同步到数据库中。
事务的四大特性:
A(atomic):原子性,事务中的全部操作是一个整体,要么全部成功,要么全部失败;
C(consistency):一致性:事务开启后,数据表中的数据状态没有变化,因为还没有提交;
I(Isolation):隔离型,多个事务操作是相互隔离,互不影响的;
D(Durability):持久性,事务一旦提交,数据表就发生永久改变.
自动提交事务和手动提交事务的区别:
自动提交事务:
在数据库工具下的测试:
数据库的数据:
自动提交事务执行select查询的结果:
用java代码测试自动提交事务时的测试结果:
@Test //自动提交事务(隐形事务时) public void testNotAddAffair(){ Connection con = JDBCTemple.getConnection(); String sql = "select count(1) from sal_table"; int count = 0; try { //查询操作 count = JDBCTemple.selectData(con,sql); System.out.println("(try中)插入前的count=" + count); //插入操作 String insert = "insert into sal_table(sname,sal) values(?,?)"; Object[] objs = {"王五", 2000}; JDBCTemple.updateDate(con,insert, objs); //再次查询操作 count = JDBCTemple.selectData(con,sql); System.out.println("(try中)插入一条数据以后的count=" + count); //插入操作 //Object[] objs1 = {"王五他大哥", 2000}; JDBCTemple.updateDate(con,insert, null); count = JDBCTemple.selectData(con,sql); System.out.println("(try中)第二次插入后的count=" + count); } catch (Exception e1) { count = JDBCTemple.selectData(con,sql); System.out.println("(catch中)出现异常后count=" + count); e1.printStackTrace(); }finally{ System.out.println("(finally中)最终count=" + count); } }
执行结果如下:
结果分析:
1.插入之前,第一次执行select查询语句时,查询到的结果是20,与工具中查的结果是一样的。
2.插入后,第二次执行select查询语句时,查询到的结果为21,说明数据可能插入到数据库中。
3.第二次插入时,因为参数是null,所以出现了空指针异常,没有成功插入到数据库中,sql执行出现异常,转到catch{}代码块中。
4.在catch{}代码块中再次查询,查询到的结果为21,说明第一次数据已经插入到数据库中。
5.在finally{}代码块中再次查询,查询的数据还是21,说明最终第一次数据插入到数据库,但是第二次没有成功插入到数据库中。
显示提交事务
在数据库工具下的测试:
手动提交事务执行select查询的结果
用java代码测试手动提交事务时的测试结果:
@Test public void testAddAffair(){ Connection con = JDBCTemple.getConnection(); String sql = "select count(1) from sal_table"; int count = 0; try { //事务的提交方式为手动提交 con.setAutoCommit(false); //查询操作 count = JDBCTemple.selectData(con,sql); System.out.println("(try中)插入前的count=" + count); //插入操作 System.out.println("开始第一次插入数据..."); String insert = "insert into sal_table(sname,sal) values(?,?)"; Object[] objs = {"王五", 2000}; JDBCTemple.updateDate(con,insert, objs); System.out.println("第一次插入数据成功!"); //再次查询操作 count = JDBCTemple.selectData(con,sql); System.out.println("(try中)插入一条数据以后的count=" + count); //插入操作 System.out.println("开始第二次插入数据...."); //Object[] objs1 = {"王五他大哥", 2000}; JDBCTemple.updateDate(con,insert, null); System.out.println("第二次插入数据成功!"); count = JDBCTemple.selectData(con,sql); System.out.println("(try中)插入两条数据以后的count=" + count); //提交事务 con.commit(); } catch (Exception e1) { try { con.rollback(); count = JDBCTemple.selectData(con,sql); System.out.println("(catch(try)中)回滚后的count=" + count); } catch (SQLException e) { System.out.println("回滚失败!"); e.printStackTrace(); b8fd } count = JDBCTemple.selectData(con,sql); System.out.println("(catch中)的count=" + count); e1.printStackTrace(); }finally{ count = JDBCTemple.selectData(con,sql); System.out.println("(finally中)最终count=" + count); } }
执行结果如下:
结果分析:
很明显的一点是:显示提交事务时,如果出现异常,那么执行结果和未执行sql语句之前的结果是一样的。
1.插入之前,第一次执行select查询语句时,查询到的结果是21,与工具中查的结果是一样的。
2.插入后,第二次执行select查询语句时,查询到的结果为22,说明这条数据可能插入到数据库中。
3.第二次插入时,因为参数是null,所以出现了空指针异常,没有成功插入到数据库中,sql执行出现异常,转到catch{}代码块中。
4.在catch{}代码块中再次查询,查询到的结果为21,又回到了第一条数据没有插入之前的结果。
5.在finally{}代码块中再次查询,查询的数据还是21,说明第一次的插入最终没有同步到数据库中
那么问题出现了,第一次插入的数据最终没有同步到数据库中,那么第一次插入后查询到的数据条数是22,这是为什么?属于幻读吗?
对于以上结果做以下分析:
1.原子性:以上所有的操作共用一个客户端的Connection对象,因为显示提交事务,所以为了保证数据的原子性,try{}代码块中的所有更新 操作属于不可分割的一部分,要么全部成功,要么全部失败。
2.是否属于幻读的问题:如果单单理解幻读史两次读取数据的行数结果不一样,那么这确实是幻读。但是真正幻读的概念是两次读取数据中间的时间间隔内,有其他的事务(其他的Connection连接)对表中数据进行了更新的操作,导致两次数据不一致的问题。在这个小demo中,始终用的是同一个Connection链接,属于同一个事务,所以不属于幻读。
3.理解第一次插入后查询到的数据条数是22,就要理解事务操作时数据库执行过程,请看下图:
从上图我们知道这个22的出现是因为:第一次插入的数据写入到了日志文件中,当我们在第一次插入后查询数据时,先从数据库表格中查到数据21,再经过日志文件处理,变成22,此时数据库表格中并没有更新。当第二次插入数据失败时,回滚数据,将日志中的记录删除,最终没有将第一次的数据同步到数据库中,所以最终数据库中的记录数还是21.
相关文章推荐
- Instance Nine:使用Transaction(事务) 手动提交,自动回滚
- mysql的事务的自动提交
- 关闭SSMS的事务自动提交,改为手动提交
- MySQL事务autocommit自动提交
- 提交表格的验证(手动和自动)
- SpringMvc Dao jdbcTemplate设置不自动提交(手动提交)(适用商品抢购等事务)
- 数据库设置自动提交事务参数(SQLSERVER、MYSQL)
- MySQL事务autocommit自动提交
- MySQL Innodb事务自动提交(autocommit)
- Postgresql:9.2.1的默认事务提交模式为手动提交(default)你可以设置称自动提交模式
- Spring与Hibernate的整合,不配置事务管理器,事务会自动提交(Hibernate默认手动提交)
- MySQL事务autocommit自动提交
- mysql事务自动提交的参数
- MySQL事务autocommit自动提交
- 【JavaWeb-25】事务管理相关知识、手动/半自动/自动管理事务案例、整合Junit、整合Web、spring和hibernate整合、struts2和spring整合
- DML需手动提交事务,DCL和DDL自动提交事务
- MySQL事务autocommit自动提交
- 使用事务实现--转账问题:从0001账户转1000块到0002账户。打开"隐式事务":设置为开,删除表中数据,回滚!(默认情况为关,如果打开了则不自动提交,学要手动提交)
- 【php】mysql事务commit自动提交
- java 服务器端验证重复提交