1、事务的4个属性
(1)Atomic原子性
(2)Consistent一致性
(3)Isolation隔离性
(4)Duration持久性
2、3种事务会出现的问题
(1)dirty read 脏读
如:A事务开始执行,并修改了资源数据,A事务未提交B事务读取A事务修改后的值,A事务可能回滚。(即:一个事务读取另一个未提交事务的数据)
(2)norepeatable-read 不可重复读
如:A事务读取数据后,中间B事务插队进来对数据进行操作(更新)并提交,当A事务在读取数据时,两次读取数据不同(不可重复读主要指更新)
(3)Phantom read幻读
如:A事务读取数据后,中间B事务插队进来对数据进行操作(删除或插入)并提交,当A事务在读取数据时,两次读取数据不同(幻象读主要指删除或插入)
3、java API Connection 五个事务级别
(1)TRANSACTION_NONE 不支持事务级别,可以不在考虑的范围之内
(2)TRANSACTION_READ_UNCOMMITTED 即在一个事务没有提交另一个事务可以进行操作,脏读,不可重复读,幻象读都可以发生。
(3)TRANSACTION_READ_COMMITTED 在一个事务提交后,另一个事务可以操作,可避免脏读
(4)TREANSACTION_REPEATABLE_READ 可重复读,可以避免脏读,不可重复读(ps:这里原理还不太清楚,知道的大侠多多拍砖)
(5)TRANSACTION_SERIALIZABLE 事务序列化,事务串行执行,可以避免上述所有事务问题,但效率差,这是必须的吗,并发性降低了
4、Hibernate对事物的处理
a.在并发性和数据处理之间的一个平衡点,一般是将事物级别设置为hibernate.connection.isolation=2,即TRANSACTION_READ_COMMITTED可以防止脏读。
b.悲观锁,在读取出来的时候加上一把锁,load(String entityName, Serializable id, LockOptions lockOptions),把LockOptions设置为LockOptions.UPGRADE
c.乐观锁,通过数据库的冗余来达到高并发,在数据库中设置一个版本字段,也即是在持久化的pojo对象中增加一个版本属性 version并用@Version 进行注解,只要一个事务对数据进行更新操作版本字段就会改变+1,这样另A个事务开始时读取的版本号与事务提交时的读入版本号不同,则说明其他事务应经动过改数据,就会抛出StaleObjectStateException,那么现在就好办了,捕获异常并进行处理就ok了
5、事务的传播行为
如:方法A--->methodA(),调用方法B---->methodB()
(1)TransactionAttributeType.REQUIRED 大概就是被调用的方法[color=red]一定[/color]会在一个事务范围中运行
[table]
|methodA()|methodB()
|在一个事务中|直接处于methodA()事务范围中进行运行
|不在在一个事务中|则为methodB启动一个新的事务
[/table]
(2)TransactionAttributeType.REQUIRED_NEW 大概就是被调用的方法[color=red]一定会在一个新的事务范围[/color]中运行
[table]
|methodA()|methodB()
|在一个事务中|a.挂起methodA当前事务b.为methodB()启动一个新的事务c.执行methodB()方法d.执行完methodB()之后恢复methodA()事务
|不在在一个事务中|则为methodB启动一个新的事务
[/table]
(3)TransactionAttributeType.MANDATORY 大概就是被调用的方法[color=red]一定会在一调用的事务范围[/color]中运行(ps:mandatory 强制的 :cry: )
[table]
|methodA()|methodB()
|在一个事务中|直接处于methodA()事务范围中进行运行
|不在在一个事务中|抛出TransactionRequiredException
[/table]
(4)TransactionAttributeType.NOT_SUPPORTED 大概就是被调用的方法[color=red]一定不会有事务范围[/color]中运行
[table]
|methodA()|methodB()
|在一个事务中|a.挂起methodA当前事务b.执行methodB()c.执行完methodB()之后恢复methodA()事务
|不在在一个事务中|执行methodB()
[/table]
(5)TransactionAttributeType.SUPPORTS 大概就是被调用的方法[color=red]可以在有事务范围或无事务范围[/color]中运行(有点嫁鸡随鸡,嫁狗随狗的感觉)
[table]
|methodA()|methodB()
|在一个事务中|在methodA()事务范围中执行
|不在在一个事务中|执行methodB()
[/table]
(6)TransactionAttributeType.NEVER大概就是被调用的方法[color=red]可一定要在事务范围[/color]中运行
[table]
|methodA()|methodB()
|在一个事务中|抛出RemoteException
|不在在一个事务中|执行methodB()
[/table]
6、EJB的事务管理
(1)CMT-->Container Manage Transaction 由容器完成事务的处理
(2)BMt --->Bean Manage Transaction 开发者通过代码完成事务的处理
参考:经典JAVA EE企业应用实战
(1)Atomic原子性
(2)Consistent一致性
(3)Isolation隔离性
(4)Duration持久性
2、3种事务会出现的问题
(1)dirty read 脏读
如:A事务开始执行,并修改了资源数据,A事务未提交B事务读取A事务修改后的值,A事务可能回滚。(即:一个事务读取另一个未提交事务的数据)
(2)norepeatable-read 不可重复读
如:A事务读取数据后,中间B事务插队进来对数据进行操作(更新)并提交,当A事务在读取数据时,两次读取数据不同(不可重复读主要指更新)
(3)Phantom read幻读
如:A事务读取数据后,中间B事务插队进来对数据进行操作(删除或插入)并提交,当A事务在读取数据时,两次读取数据不同(幻象读主要指删除或插入)
3、java API Connection 五个事务级别
(1)TRANSACTION_NONE 不支持事务级别,可以不在考虑的范围之内
(2)TRANSACTION_READ_UNCOMMITTED 即在一个事务没有提交另一个事务可以进行操作,脏读,不可重复读,幻象读都可以发生。
(3)TRANSACTION_READ_COMMITTED 在一个事务提交后,另一个事务可以操作,可避免脏读
(4)TREANSACTION_REPEATABLE_READ 可重复读,可以避免脏读,不可重复读(ps:这里原理还不太清楚,知道的大侠多多拍砖)
(5)TRANSACTION_SERIALIZABLE 事务序列化,事务串行执行,可以避免上述所有事务问题,但效率差,这是必须的吗,并发性降低了
4、Hibernate对事物的处理
a.在并发性和数据处理之间的一个平衡点,一般是将事物级别设置为hibernate.connection.isolation=2,即TRANSACTION_READ_COMMITTED可以防止脏读。
b.悲观锁,在读取出来的时候加上一把锁,load(String entityName, Serializable id, LockOptions lockOptions),把LockOptions设置为LockOptions.UPGRADE
c.乐观锁,通过数据库的冗余来达到高并发,在数据库中设置一个版本字段,也即是在持久化的pojo对象中增加一个版本属性 version并用@Version 进行注解,只要一个事务对数据进行更新操作版本字段就会改变+1,这样另A个事务开始时读取的版本号与事务提交时的读入版本号不同,则说明其他事务应经动过改数据,就会抛出StaleObjectStateException,那么现在就好办了,捕获异常并进行处理就ok了
5、事务的传播行为
如:方法A--->methodA(),调用方法B---->methodB()
(1)TransactionAttributeType.REQUIRED 大概就是被调用的方法[color=red]一定[/color]会在一个事务范围中运行
[table]
|methodA()|methodB()
|在一个事务中|直接处于methodA()事务范围中进行运行
|不在在一个事务中|则为methodB启动一个新的事务
[/table]
(2)TransactionAttributeType.REQUIRED_NEW 大概就是被调用的方法[color=red]一定会在一个新的事务范围[/color]中运行
[table]
|methodA()|methodB()
|在一个事务中|a.挂起methodA当前事务b.为methodB()启动一个新的事务c.执行methodB()方法d.执行完methodB()之后恢复methodA()事务
|不在在一个事务中|则为methodB启动一个新的事务
[/table]
(3)TransactionAttributeType.MANDATORY 大概就是被调用的方法[color=red]一定会在一调用的事务范围[/color]中运行(ps:mandatory 强制的 :cry: )
[table]
|methodA()|methodB()
|在一个事务中|直接处于methodA()事务范围中进行运行
|不在在一个事务中|抛出TransactionRequiredException
[/table]
(4)TransactionAttributeType.NOT_SUPPORTED 大概就是被调用的方法[color=red]一定不会有事务范围[/color]中运行
[table]
|methodA()|methodB()
|在一个事务中|a.挂起methodA当前事务b.执行methodB()c.执行完methodB()之后恢复methodA()事务
|不在在一个事务中|执行methodB()
[/table]
(5)TransactionAttributeType.SUPPORTS 大概就是被调用的方法[color=red]可以在有事务范围或无事务范围[/color]中运行(有点嫁鸡随鸡,嫁狗随狗的感觉)
[table]
|methodA()|methodB()
|在一个事务中|在methodA()事务范围中执行
|不在在一个事务中|执行methodB()
[/table]
(6)TransactionAttributeType.NEVER大概就是被调用的方法[color=red]可一定要在事务范围[/color]中运行
[table]
|methodA()|methodB()
|在一个事务中|抛出RemoteException
|不在在一个事务中|执行methodB()
[/table]
6、EJB的事务管理
(1)CMT-->Container Manage Transaction 由容器完成事务的处理
(2)BMt --->Bean Manage Transaction 开发者通过代码完成事务的处理
参考:经典JAVA EE企业应用实战