事务处理
事务(Transaction)是访问并可能更新数据库中各种数据项的一个程序执行单元(unit)。
事务应该具有4个属性:原子性、一致性、隔离性、持续性。这四个属性通常称为ACID特性。
原子性(atomicity)。一个事务是一个不可分割的工作单位,事务中包括的诸操作要么都做,要么都不做。
一致性(consistency)。事务必须是使数据库从一个一致性状态变到另一个一致性状态。一致性与原子性是密切相关的。
隔离性(isolation)。一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。
持久性(durability)。持续性也称永久性(permanence),指一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。接下来的其他操作或故障不应该对其有任何影响。
一般的事务是由很多个操作组成的,所以事务一般放在业务逻辑层,低耦合,高内聚。
ibatis里事务一般分为主动事务和被动事务,在全局事务概念下
主动参与事务:iBATIS会查看现有事务的状态,并且在必要的时候主动开始一个事务,当事务失败时,会通知所有相关事务资源,执行rollback。
被动事务:iBATIS忽略当前应用程序中所有关于开始事务,提交事务,结束事务的指定代码,不是主动rollback,而是抛出异常。
SqlMapClient接口里的事务相关的三个方法:
- public void myPointcut();
- public void startTransaction () throws SQLException ;
- public void commitTransaction () throws SQLException ;
- public void endTransaction () throws SQLException ;
- 例子:
- public updateItemDescription (String itemId, String newDescription) throws SQLException
- {
- try { sqlMap.startTransaction ();
- Item item = (Item) sqlMap.queryForObject ("getItem", itemId);
- item.setDescription (newDescription);
- sqlMap.update ("updateItem", item);
- sqlMap.commitTransaction ();
- } finally
- {
- sqlMap.endTransaction ();
- }
- }
public void myPointcut();
public void startTransaction () throws SQLException ;
public void commitTransaction () throws SQLException ;
public void endTransaction () throws SQLException ;
例子:
public updateItemDescription (String itemId, String newDescription) throws SQLException
{
try { sqlMap.startTransaction ();
Item item = (Item) sqlMap.queryForObject ("getItem", itemId);
item.setDescription (newDescription);
sqlMap.update ("updateItem", item);
sqlMap.commitTransaction ();
} finally
{
sqlMap.endTransaction ();
}
}
jdbc事务:Connection对象默认是自动提交事务模式,如果屏蔽(setAutoCommit(true)),则需要显式调用。iBATIS同样支持自己管理事务
例如:
- public void runStatementsUsingSetUserConnection() {
- SqlMapClient sqlMapClient =
- SqlMapClientConfig.getSqlMapClient();
- Connection conn = null;
- try {
- conn = dataSource.getConnection();
- conn.setAutoCommit(false);
- sqlMapClient.setUserConnection(conn);
- Person p =
- (Person)sqlMapClient.queryForObject
- ("getPerson", new Integer(9));
- p.setLastName("Smith");
- sqlMapClient.update("updatePerson", p);
- Department d =
- (Department)sqlMapClient.queryForObject
- ("getDept", new Integer(3));
- p.setDepartment(d);
- sqlMapClient.update("updatePersonDept", p);
- conn.commit();
- } finally {
- sqlMapClient.setUserConnection(null);
- if (conn != null) conn.close();
- }
- }
- 也可以使用openSession
- public void runStatementsUsingSetUserConnection() {
- SqlMapClient sqlMapClient =
- SqlMapClientConfig.getSqlMapClient();
- Connection conn = null;
- SqlMapSession session = null;
- try {
- conn = dataSource.getConnection();
- conn.setAutoCommit(false);
- session = sqlMapClient.openSession(conn);
- Person p =
- (Person)session.queryForObject("getPerson",
- new Integer(9));
- p.setLastName("Smith");
- session.update("updatePerson", p);
- Department d =
- (Department)session.queryForObject
- ("getDept", new Integer(3));
- p.setDepartment(d);
- session.update("updatePersonDept", p);
- conn.commit();
- } finally {
- if (session != null) session.close();
- if (conn != null) conn.close();
- }
- }
public void runStatementsUsingSetUserConnection() {
SqlMapClient sqlMapClient =
SqlMapClientConfig.getSqlMapClient();
Connection conn = null;
try {
conn = dataSource.getConnection();
conn.setAutoCommit(false);
sqlMapClient.setUserConnection(conn);
Person p =
(Person)sqlMapClient.queryForObject
("getPerson", new Integer(9));
p.setLastName("Smith");
sqlMapClient.update("updatePerson", p);
Department d =
(Department)sqlMapClient.queryForObject
("getDept", new Integer(3));
p.setDepartment(d);
sqlMapClient.update("updatePersonDept", p);
conn.commit();
} finally {
sqlMapClient.setUserConnection(null);
if (conn != null) conn.close();
}
}
也可以使用openSession
public void runStatementsUsingSetUserConnection() {
SqlMapClient sqlMapClient =
SqlMapClientConfig.getSqlMapClient();
Connection conn = null;
SqlMapSession session = null;
try {
conn = dataSource.getConnection();
conn.setAutoCommit(false);
session = sqlMapClient.openSession(conn);
Person p =
(Person)session.queryForObject("getPerson",
new Integer(9));
p.setLastName("Smith");
session.update("updatePerson", p);
Department d =
(Department)session.queryForObject
("getDept", new Integer(3));
p.setDepartment(d);
session.update("updatePersonDept", p);
conn.commit();
} finally {
if (session != null) session.close();
if (conn != null) conn.close();
}
}
2 高速缓存
iBATIS里主要是在xml文件里进行一些配置
<cacheModel id=”productCache” type=”LRU”> <flushInterval hours=”24”/> <property name=”size” value=”1000” /> </cacheModel>
cacheModel有四个属性,id,type,serializable,readonly,后两个属性可以设置为true或false
type为缓存的模式,有四种MEMORY,LRU,FIFO,OSCACHE
- <cacheModel id="product-cache" type="MEMORY">
- <flushInterval hours="24"/> //每隔多长时间更新,hours,minutes,seconds等
- <flushOnExecute statement="insertProduct"/> //定义的映射id,当执行insertProduct时,执行高速缓存
- <flushOnExecute statement="updateProduct"/>
- <flushOnExecute statement="deleteProduct"/>
- <property name=”reference-type” value=”WEAK” /> //MEMORY cache实现只认识一个<property>元素。这个名为“reference-type”属性的值必须是STRONG,SOFT和WEAK三者其一。
- 默认是weak,让垃圾处理器去处理
- </cacheModel>
- <cacheModel id="product-cache" type="LRU">
- <flushInterval hours="24"/>
- <flushOnExecute statement="insertProduct"/>
- <flushOnExecute statement="updateProduct"/>
- <flushOnExecute statement="deleteProduct"/>
- <property name=”size” value=”1000” /> //缓冲区大小
- </cacheModel>
- <cacheModel id="product-cache" type="FIFO">
- <flushInterval hours="24"/>
- <flushOnExecute statement="insertProduct"/>
- <flushOnExecute statement="updateProduct"/>
- <flushOnExecute statement="deleteProduct"/>
- <property name=”size” value=”1000” />
- </cacheModel>
- <cacheModel id="product-cache" type="OSCACHE">
- <flushInterval hours="24"/>
- <flushOnExecute statement="insertProduct"/>
- <flushOnExecute statement="updateProduct"/>
- <flushOnExecute statement="deleteProduct"/>
- </cacheModel>
<cacheModel id="product-cache" type="MEMORY"> <flushInterval hours="24"/> //每隔多长时间更新,hours,minutes,seconds等 <flushOnExecute statement="insertProduct"/> //定义的映射id,当执行insertProduct时,执行高速缓存 <flushOnExecute statement="updateProduct"/> <flushOnExecute statement="deleteProduct"/> <property name=”reference-type” value=”WEAK” /> //MEMORY cache实现只认识一个<property>元素。这个名为“reference-type”属性的值必须是STRONG,SOFT和WEAK三者其一。 默认是weak,让垃圾处理器去处理 </cacheModel> <cacheModel id="product-cache" type="LRU"> <flushInterval hours="24"/> <flushOnExecute statement="insertProduct"/> <flushOnExecute statement="updateProduct"/> <flushOnExecute statement="deleteProduct"/> <property name=”size” value=”1000” /> //缓冲区大小 </cacheModel> <cacheModel id="product-cache" type="FIFO"> <flushInterval hours="24"/> <flushOnExecute statement="insertProduct"/> <flushOnExecute statement="updateProduct"/> <flushOnExecute statement="deleteProduct"/> <property name=”size” value=”1000” /> </cacheModel> <cacheModel id="product-cache" type="OSCACHE"> <flushInterval hours="24"/> <flushOnExecute statement="insertProduct"/> <flushOnExecute statement="updateProduct"/> <flushOnExecute statement="deleteProduct"/> </cacheModel>
实际用法
- <select id=”getProductList” cacheModel=”productCache”>
- select * from PRODUCT where PRD_CAT_ID = #value#
- </select>
<select id=”getProductList” cacheModel=”productCache”> select * from PRODUCT where PRD_CAT_ID = #value# </select>
转载自:http://crazycat03.iteye.com/blog/550491