- Jdbc事务隔离级别
Jdbc隔离级别 | 数据库隔离级别 | 数据访问情况 |
---|---|---|
TRANSACTION_READ_UNCOMMITTED(未提交读)Uncommitted Read | ur | 脏读,在没有提交数据的时候能够读到已经更新的数据 |
TRANSACTION_READ_COMMITTED(提交读) | cs | 不可重复读,事务A读取数据,事务B修改数据并提交,事务A再次查询时将会查到事务B提交的数据。 |
TRANSACTION_REPEATABLE_READ(重复读) | rs | 幻读,事务A读取数据,锁定数据记录,其他事务不能修改被事务A锁定的记录,但可以插入新的数据。 |
TRANSACTION_SERIALIZABLE(序列化) | rr | 序列化,事务顺序挨个执行。避免了幻读。 |
Db2缺省情况下使用cs
以下说明使用到表t_bs_user,该表有如下字段:id,name,zt。
未提交读:
事务A读取到t_bs_user表中的id为1的数据zt为0,此时事务B修改了id为1的数据,将zt置为1,但是没有提交,事务A再次读取t_bs_user表的数据,发现zt为1,如果事务B做了回滚操作,那么事务A读取的将是脏数据。脏读可以通过增加事务隔离级别来避免。
提交读:
事务A读取到t_bs_user表中的id为1的数据zt为0,此时事务B修改了id为1的数据,将zt置为1,并提交,事务A再次读取t_bs_user表的数据,发现zt为1。这样就发生了不可重复读,事务A两次读取的数据不一样。不可重复读可以通过增加事务隔离级别来避免。
重复读:
事务A读取到t_bs_user表中的id为1的数据zt为0,并锁定此行数据,其他事务将无法对此行数据进行修改,但可以insert新的数据,事务A再次读取t_bs_user表中的数据,将会发现有新的数据,这个现象就是“幻读”。
序列化:
各个事务依次执行,不仅可以避免脏读、不可重复读,还避免了幻读。事务隔离级别最高,代价高,性能低,一般很少使用。
- db2锁
⑴ 引言
在关系型数据库(BD2,Oracle,Sybase,Informix和Sql Server)最小的恢复和交易单位为一个事务,事务具有ACID(原子性,一致性,隔离性,永久性)特征。关系数据库为了确保并发用户在存取同一数据库对象的正确性(即无脏读,无丢失更新,可重复读,无幻读),数据库中引入了锁机制。基本的锁类型:共享锁S和排它锁X。
排它锁:如果事务A对数据D加X锁,则其他任何事务都不能再对数据D加任何类型的锁,直至事务A释放数据D上的X锁;一般要求在修改数据前要向该数据加排它锁,所以排它锁又称为写锁。如果事务隔离级别是ur(未提交读),更新数据时是没有加排它锁的。
共享锁:如果事务A对数据D加S锁,则其他事务只能对数据D加S锁,而不能加X锁,直至事务A释放D上的S锁;一般要求在读取数据前要向该数据加共享锁,所以共享锁又称读锁。
⑵ DB2多力度封锁机制
锁的对象
DB2支持对表空间、表、行和索引加锁(大型机上的数据库还可以支持对数据页加锁)来保证数据库的并发完整性。不过在考虑用户应用程序的并发性的问题上,通常并不检查用于表空间和索引的锁。该类问题分析的焦点在于表锁和行锁。
锁的策略
DB2可以只对表进行加锁,也可以对表和表中的行进行加锁。如果只对表进行加锁,则表中所有的行都受到同等程度的影响。如果加锁的范围针对于表及下属的行,则在对表加锁后,相应的数据行上还要加锁。究竟应用程序是对表加行锁还是同时加表锁和行锁,是由应用程序执行的命令和系统的隔离级别确定。
DB2表锁的模式
表一:DB2数据库表锁的模式
下面对几种表锁的模式进一步加以阐述:
IS、IX、SIX方式用于表一级并需要行锁配合,他们可以阻止其他应用程序对该表加上排它锁。
- 如果一个应用程序获得某表的IS锁,该应用程序可获得某一行上的S锁,用于只读操作,同时其他应用程序也可以读取该行,或是对表中的其他行进行更改。
- 如果一个应用程序获得某表的IX锁,该应用程序可获得某一行上的X锁,用于更改操作,同时其他应用程序可以读取或更改表中的其他行。
- 如果一个应用程序获得某表的SIX锁,该应用程序可以获得某一行上的X锁,用于更改操作,同时其他应用程序只能对表中其他行进行只读操作。
S、U、X和Z方式用于表一级,但并不需要行锁配合,是比较严格的表加锁策略。
- 如果一个应用程序得到某表的S锁。该应用程序可以读表中的任何数据。同时它允许其他应用程序获得该表上的只读请求锁。如果有应用程序需要更改读该表上的数据,必须等S锁被释放。
- 如果一个应用程序得到某表的U锁,该应用程序可以读表中的任何数据,并最终可以通过获得表上的X锁来得到对表中任何数据的修改权。其他应用程序只能读取该表中的数据。U锁与S锁的区别主要在于更改的意图上。U锁的设计主要是为了避免两个应用程序在拥有S锁的情况下同时申请X锁而造成死锁的。
- 如果一个应用程序得到某表上的X锁,该应用程序可以读或修改表中的任何数据。其他应用程序不能对该表进行读或者更改操作。
- 如果一个应用程序得到某表上的Z锁,该应用程序可以读或修改表中的任何数据。其他应用程序,包括未提交读程序都不能对该表进行读或者更改操作。
- IN锁用于表上以允许未提交读这一概念。
DB2行锁的模式
表二:DB2数据库行锁的模式
2.2.3 DB2锁的兼容性
表三:DB2数据库表锁的相容矩阵
表四:DB2数据库行锁的相容矩阵
下表是本篇文章的作者总结了DB2中各SQL语句产生表锁的情况(假设缺省的隔离级别为CS):
DB2锁的升级
每个锁在内存中都需要一定的内存空间,为了减少锁需要的内存开销,DB2提供了锁升级的功能。锁升级是通过对表加上非意图性的表锁,同时释放行锁来减少锁的数目,从而达到减少锁需要的内存开销的目的。锁升级是由数据库管理器自动完成的,有两个数据库的配置参数直接影响锁升级的处理:
locklist–在一个数据库全局内存中用于锁存储的内存。单位为页(4K)。
maxlocks–一个应用程序允许得到的锁占用的内存所占locklist大小的百分比。
锁升级会在这两种情况下被触发:
- 某个应用程序请求的锁所占用的内存空间超出了maxlocks与locklist的乘积大小。这时,数据库管理器将试图通过为提出锁请求的应用程序申请表锁,并释放行锁来节省空间。
- 在一个数据库中已被加上的全部锁所占的内存空间超出了locklist定义的大小。这时,数据库管理器也将试图通过为提出锁请求的应用程序申请表锁,并释放行锁来节省空间。
- 锁升级虽然会降低OLTP应用程序的并发性能,但是锁升级后会释放锁占有内存并增大可用的锁的内存空间。
锁升级是有可能会失败的,比如,现在一个应用程序已经在一个表上加有IX锁,表中的某些行上加有X锁,另一个应用程序又来请求表上的IS锁,以及很多行上的S锁,由于申请的锁数目过多引起锁的升级。数据库管理器试图为该应用程序申请表上的S锁来减少所需要的锁的数目,但S锁与表上原有的IX锁冲突,锁升级不能成功。
如果锁升级失败,引起锁升级的应用程序将接到一个-912的SQLCODE。在锁升级失败后,DBA应该考虑增加locklist的大小或者增大maxlocks的百分比。同时对编程人员来说可以在程序里对发生锁升级后程序回滚后重新提交事务(例如:if sqlca.sqlcode=-912 then rollback and retry等)。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/182070.html原文链接:https://javaforall.cn