一、什么是JAVA事物
事务是访问数据库的一个操作序列,数据库应用系统通过事务集来完成对数据库的存取。事务的正确执行使得数据库从一种状态转换成另一种状态。
英文解释: A database transaction is a larger unitthat frames multiple SQL statements. A transaction ensures that the action ofthe framed statements is atomic with respect to recovery.
事务是确保"同时成功则成功,任何一个失败则失败"的一种机制。一个事务往往包括三种动作行为:开始事务(BeginTransaction),提交事务(Commit)和回滚(Rollback)。从开始事务到提交事务过程中所发生的一切数据库修改要么同时成功(被Commit,固化在数据库中),要么一个失败,大家同时回复原有状态(Rollback,数据库回复到事务开始时的状态)。
简单的理解:它是一个操作序列,这些操作要么都执行,要么都不执行,它是一个不可分割的工作单位。
既然事务的概念从数据库而来,那Java事务是什么?之间有什么联系?
实际上,一个Java应用系统,如果要操作数据库,则通过JDBC来实现的。增加、修改、删除都是通过相应方法间接来实现的,事务的控制也相应转移到Java程序代码中。因此,数据库操作的事务习惯上就称为Java事务。
事物必须服从ISO/IEC所制定的ACID原则。ACID即:原子性(atomicity)、一致性(consistency)、隔离性(isolation)、持久性(durability)。
1、 原子性:即不可分割性,事务要么全部被执行,要么就全部不被执行。如果事务的所有子事务全部提交成功,则所有的数据库操作被提交,数据库状态发生转换;如果有子事务失败,则其他子事务的数据库操作被回滚,即数据库回到事务执行前的状态,不会发生状态转换。
2、 一致性:事务的执行使得数据库从一种正确状态转换成另一种正确状态。一致性与原子性密切相关。
3、 隔离性:一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。通俗的说就是在事务正确提交之前,不允许把该事务对数据的任何改变提供给任何其他事务。
4、 持久性:事务正确提交后,其结果将永久保存在数据库中,即使在事务提交后有了其他故障,事务的处理结果也会得到保存。
二、事物的分类:
1、 本地事物(Local transaction):只有一个数据源参与的事物,比如只有单个数据库或者只有JMS。
2、 分布式事务(Distributed transaction):多个数据源同时参与的事物,比如一个操作同时访问多个数据库,或者一个操作在访问数据库的同时通过JMS发送消息。
三、事物的并发控制与隔离
多个事物同时执行,并且不进行必要的隔离控制,就会导致各种并发问题,一般有以下几类:
1、 第一类丢失更新(Lost update):撤销一个事务时,把其他事务已提交的更新数据覆盖。场景:AB事物并发执行,A执行更新后,提交,B在A提交之后也对改数据执行更新操作,然后回滚,导致两次更新的数据丢失。
2、 脏读(Dirty reads):一个事务读到另一个事务未提交的更新数据。场景:AB事物并发执行,A执行更新后,B查询A未提交的数据,然后A回滚,导致B读取到与数据库中不一致的数据,即脏数据。
3、 不可重复读(Non-repeatable reads): 一个事务读到另一个事务已提交的更新数据。场景:AB事物并发执行,A查询数据,然后B更新数据,A再次查询数据,发现该数据改变。
4、 第二类丢失更新(Second lost update): 这是不可重复读中的特例,一个事务覆盖另一个事务已提交的更新数据。场景:AB事物并发执行,A更新数据,然后B更新数据,A查询数据发现自己更新的数据改变了。
5、 幻象读(Phantom reads): 一个事务读到另一个事务已提交的新插入的数据。场景: AB事物并发执行,A查询数据,然后B插入或者删除数据,A再次查询发现数据多了或者少了。
隔离级别:
1、 未提交读(Read uncommitted):一个事务在执行过程中可以拷贝其他事务未提交的新插入的记录,而且能看到其他事务没有提交的对已有记录的更新。
2、 已提交读(Read committed):一个事务在执行过程中可以拷贝其他事务已提交的新插入的记录,而且能看到其他事务没有提交的对已有记录的更新。
3、 重复读(Repeatable read):一个事务在执行过程中可以看到其他事务已经提交的新插入的记录,但是不能看到其他事务对已有记录的更新。
4、 串行化(Serializable):一个事务在执行过程中完全看不到其他事务对数据库所做的更新。
隔离级别越高,越能保证数据的完整性和一致性,但是对并发性能的影响也越大。
隔离级别对并发的控制:
Yes表示出现异常,No表示不会出现异常
| 第一类丢失更新 | 脏读 | 不可重复读 | 第二类丢失更新 | 幻象读 |
未提交读 | Yes | Yes | Yes | Yes | Yes |
已提交读 | No | No | Yes | Yes | Yes |
重复读 | No | No | No | No | Yes |
串行化 | No | No | No | No | No |
四、JAVA事物的类型以及差别:
JDBC事物、JTA(java transaction API)、容器事物。
这三种事物之间的差别:
1、 JDBC控制事物的局限性在于一个数据库类的连接,不能跨越多个数据库。
2、 JTA事务的功能强大,事务可以跨越多个数据库或多个DAO,使用也比较复杂。
3、 容器事务,主要指的是J2EE应用服务器提供的事务管理,局限于EJB应用使用。
根据三种事物的差别知道:事物控制对于J2EE应用是必不可少的,合理应用各种事物对应用系统至关重要,在单个jdbc连接的情况使用JDBC事物,在跨多个连接或者多个数据库的情况下,使用JTA事物,如果用到了EJB可考虑容器事物。