#TangYuan之事务数据库
Tangyuan中,咱们能够经过如下配置定义一个事务:并发
<transaction id="tx_01" behavior="required" isolation="default" />
transaction节点属性说明:ui
属性名 | 用途及说明 | 必填 | 取值 |
---|---|---|---|
id | 事务定义标识,不可重复 | Y | 用户定义 |
behavior | 事务的传播级别,默认required,可参考Spring事务,默认required | N | required<br />supports<br />mandatory<br />requires_new<br />not_supported<br />never<br /> |
never | 事务的隔离级别,默认default | N | default<br />read_uncommitted<br />read_committed<br />repeatable_read<br />serializable<br /> |
behavior事务传播属性说明:设计
取值 | 用途说明 |
---|---|
required | 表示当前方法必须在一个具备事务的上下文中运行,若有客户端有事务在进行,那么被调用端将在该事务中运行,不然的话从新开启一个事务。 |
supports | 表示当前方法没必要须要具备一个事务上下文,可是若是有一个事务的话,它也能够在这个事务中运行 |
mandatory | 表示当前方法必须在一个事务中运行,若是没有事务,将抛出异常 |
requires_new | 表示当前方法必须运行在它本身的事务中。一个新的事务将启动,并且若是有一个现有的事务在运行的话,则这个方法将在运行期被挂起,直到新的事务提交或者回滚才恢复执行。 |
not_supported | 表示该方法不该该在一个事务中运行。若是有一个事务正在运行,他将在运行期被挂起,直到这个事务提交或者回滚才恢复执行 |
never | 表示当方法务不该该在一个事务中运行,若是存在一个事务,则抛出异常 |
isolation说明:code
取值 | 用途说明 |
---|---|
default | 默认设置,同read_uncommitted |
read_uncommitted | 脏读<br /> * 脏读又称无效数据的读出,是指在数据库访问中,事务T1将某一值修改,而后事务T2读取该值,此后T1由于某种缘由撤销对该值的修改,这就致使了T2所读取到的数据是无效的。<br /> * 脏读就是指当一个事务正在访问数据,而且对数据进行了修改,而这种修改尚未提交到数据库中,这时,另一个事务也访问这个数据,而后使用了这个数据。 由于这个数据是尚未提交的数据,那么另一个事务读到的这个数据是脏数据,依据脏数据所作的操做多是不正确的。 |
read_committed | 不可重复读<br /> * 不可重复读,是指在数据库访问中,一个事务范围内两个相同的查询却返回了不一样数据。<br /> * 这是因为查询时系统中其余事务修改的提交而引发的。好比事务T1读取某一数据,事务T2读取并修改了该数据,T1为了对读取值进行检验而再次读取该数据,便获得了不一样的结果。<br /> * 一种更易理解的说法是:在一个事务内,屡次读同一个数据。在这个事务尚未结束时,另外一个事务也访问该同一数据。<br /> * 那么,在第一个事务的两次读数据之间。因为第二个事务的修改,那么第一个事务读到的数据可能不同,这样就发生了在一个事务内两次读到的数据是不同的,所以称为不可重复读,即原始读取不可重复。 |
repeatable_read | 可重复读取<br />* 可重复读(Repeatable Read),当使用可重复读隔离级别时,在事务执行期间会锁定该事务以任何方式引用的全部行。 所以,若是在同一个事务中发出同一个SELECT语句两次或更屡次,那么产生的结果数据集老是相同的。<br /> * 所以,使用可重复读隔离级别的事务能够屡次检索同一行集,并对它们执行任意操做,直到提交或回滚操做终止该事务。 |
serializable | 同步事务<br /> * 提供严格的事务隔离。它要求事务序列化执行,事务只能一个接着一个地执行,但不能并发执行。<br /> * 若是仅仅经过“行级锁”是没法实现事务序列化的,必须经过其余机制保证新插入的数据不会被刚执行查询操做的事务访问到。 |
有了上述事务的定义,接下来开始事务的使用。Tangyuan中每一个SQL服务都须要使用事务,或者说每一个SQL服务在执行期间都须要按照指定的事务定义开启事务,执行SQL命令。咱们能够经过三种方式设置SQL服务使用的事务定义。事务
1.在SQL服务中,手工设置get
<selectOne id="getUserById" txRef="tx_01" dsKey="ds"> SELECT * from user WHERE user_id = #{user_id} </selectOne>
示例中的配置经过txRef
属性手工指定使用tx_01
的事务定义同步
2.按照SQL服务ID匹配it
<setDefaultTransaction type="method"> <property name="select*" value="tx_01"/> <property name="get*" value="tx_01"/> <property name="update*" value="tx_02"/> <property name="insert*" value="tx_02"/> <property name="delete*" value="tx_02"/> </setDefaultTransaction>
示例中的配置表示按照SQL服务的名称也就是ID来匹配须要使用的事务定义。好比SQL服务selectUser
将使用tx_01
事务定义,SQL服务updateUser
将使用tx_02
事务定义,须要注意的复合SQL将不会根据setDefaultTransaction
来匹配事务,须要用户手工指定。io
3.按照SQL服务类型匹配
<setDefaultTransaction type="command"> <property name="selectOne" value="tx_01"/> <property name="selectSet" value="tx_01"/> <property name="update" value="tx_01"/> <property name="insert" value="tx_01"/> <property name="delete" value="tx_01"/> </setDefaultTransaction>
示例中的配置表示按照SQL服务的类型也就是标签来匹配须要使用的事务定义。好比用<selectOne>
标签订义SQL服务将使用tx_01
事务定义,用<update>
标签订义的SQL服务将使用tx_02
事务定义,须要注意的复合SQL将不会根据setDefaultTransaction
来匹配事务,须要用户手工指定。
Schema设计图
setDefaultTransaction节点属性说明
属性名 | 用途及说明 | 必填 | 取值 |
---|---|---|---|
type | 默认事务的匹配模式 | Y | method:按照SQL服务的名称匹配<br />command:按照SQL服务的类型匹配 |
property节点属性说明
属性名 | 用途及说明 | 必填 | 取值 |
---|---|---|---|
name | method模式下:SQL服务名称,支持*表达式<br />command模式下:SQL服务标签名 | Y | 用户定义 |
value | 须要引用的事务定义ID | Y | 用户定义 |