newxy
新坐標的事務管理
?作者:胡立新
一、簡介
newxy(新坐標)可以同時對多個數據庫進行事務管理,newxy(新坐標)的事務由類net.newxy.dbm.Transaction來完成。
newxy(新坐標)目前只支持本地事務(在未來版本中,如果數據庫連接有JTA的支持,那么在newxy(新坐標)事務中進行的操作將是整個原子性JTA事務的一部分)。
?????? ?一個Transaction實例除有一個主線程外,還有一個專門負責超時回滾任務的線程。主線程負責對一批需要一次性完成的單元進行操作。如果在設定或默認的時間內主線程一批操作尚未完成,負責超時回滾任務的線程會干預,回滾事務。
??? newxy(新坐標)的事務管理很方便,只需在調用IFacade接口方法前調用事務方法call(IFacade ifacade), 或方法call(IFacade ifacade,int transactionIsolation),如 tran.call(ifacade).update(dto)。
?
二、運用舉例:
設有數據庫有兩表:
/*客戶表*/
create table customers (
??? id int primary key,
??? name VARCHAR(255)
)
/*訂單表*/
create table orders (
??? id int primary key,
??? customer_id int,
??? date datetime
)
運用一
//新建一名叫“張五”的客戶,新建一與此用戶關聯的定單,訂單表字段customer_id是“張五”客戶的id號,
//id號由系統自動生成。
package common;
?
import
net.newxy.dbm.*;
import
org.apache.commons.beanutils.DynaBean;
?
public class Test{
??? public static void main(String[] args) {
??????? TestSqlServerDao dao1=new TestSqlServerDao();
?
??????? DynaDto customerDto=new DynaDto();
??????? customerDto.set_table("customers");
??????? customerDto.set("name","張五");
?
??????? DynaDto ordersDto=new DynaDto();
??????? ordersDto.set_table("orders");
??????? ordersDto.set("date",net.newxy.util.DateTools.todayInTs());
?
??????? Transaction tran=new Transaction();
??????? try{
??????????? tran.begin();
??????????? Object result1=tran.call(dao1).update(customerDto);
??????????? if(result1!=null){
??????????????? // result不等于空,表明是插入操作,且result中包含了自動生成的主關鍵字值。
??????????????? ordersDto.set("customer_id",((DynaBean)result1).get("id"));
??????????? }else{
??????????????? // result為空,表明是update操作,客戶id保存在customerDto中。
??????????????? // 此例因為沒有給customerDto設置id,因而肯定是自動獲得id值后作插入操作,
??????????????? // result肯定不為空。
??????????????? ordersDto.set("customer_id",customerDto.get("id"));
??????????? }
??????????? tran.call(dao1).update(ordersDto);
??????????? tran.commit();
??????? }catch(Exception e2){
??????????? try {
??????????????? tran.rollback();
??????????? } catch (Exception ex) {
??????????? }
???? ???????System.out.println(e2.getMessage());
??????? }
??? }
}
?
//dao類TestSqlServerDao
package common;
?
import
java.sql.DriverManager;
import
java.sql.Connection;
import
java.sql.SQLException;
import
net.newxy.dbm.BaseDAO;
?
public class TestSqlServerDao extends BaseDAO{
??? public TestSqlServerDao(){
??????? super();
}
??? public Connection getConnection(String dsJndi) throws Exception {
??????? Connection cn=null;
??????? try {
??????????? Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver").newInstance();
??????????? cn = DriverManager.getConnection(
??????????????????????? "jdbc:microsoft:sqlserver://localhost:1433; SendStringParametersAsUnicode=false","webUser","myPass");
??????? } catch (ClassNotFoundException ex) {
??????? } catch (IllegalAccessException ex) {
??????? } catch (InstantiationException ex) {
??????? } catch (SQLException ex1) {
??????????? throw new Exception(ex1.getMessage());
??????? }
??????? return cn;
??? }
}
運用二
??? //默認的60秒后,負責超時回滾任務的線程將檢查事務是否已完成,如果沒完成,回滾事務。
??? //設置超時時間的方法是:
??????? Transaction tran=new Transaction();
??????? tran.setTransactionTimeout(10);
??????? try{
??????????? tran.begin();
??????????? ......
??????????? tran.commit();
??????? }catch(Exception e2){
??????????? try {
??????????????? tran.rollback();
??????????? } catch (Exception ex) {
??????????? }
??????????? System.out.println(e2.getMessage());
??????? }
運用三
??? //設置事務隔離等級:
??????? Transaction tran=new Transaction();
??????? tran.setTransactionIsolation(java.sql.Connection.TRANSACTION_READ_UNCOMMITTED);
??????? try{
??????????? tran.begin();
??????????? ......
??????????? tran.commit();
??????? }catch(Exception e2){
??????????? try {
??????????????? tran.rollback();
??????????? } catch (Exception ex) {
??????????? }
??????????? System.out.println(e2.getMessage());
??????? }
運用四
??? // 事務同時對多個數據庫操作。方法是,如同dao類TestSqlServerDao,再建另一dao類Dao2,
??? // Dao2實現的getConnection(String dsJndi)方法獲得另一數據庫連接。
?
??????? TestSqlServerDao dao1=new TestSqlServerDao();
??????? Dao2 dao2=new Dao2();
?
??????? Transaction tran=new Transaction();
??????? try{
??????????? tran.begin();
??????????? ......
??????????? tran.call(dao1,).update(...);
??????????? tran.call(dao2).remove(...);
?
??????????? ......
??????????? tran.commit();
??????? }catch(Exception e2){
??????????? try {
??????????????? tran.rollback();
??????????? } catch (Exception ex) {
??????????? }
??????????? System.out.println(e2.getMessage());
??????? }
運用五
??? //事務中開發者自己要直接運用數據庫連接,但開發者不能在事務中關閉數據庫連接。
??????? TestSqlServerDao dao1=new TestSqlServerDao();
??????? Transaction tran=new Transaction();
??????? try{
??????????? tran.begin();
??????????? ......
??????????? Connection con=tran.call(dao1).getConnection();
??????????? ......
??????????? tran.commit();
??????? }catch(Exception e2){
??????????? try {
??????????????? tran.rollback();
??????????? } catch (Exception ex) {
??????????? }
??????????? System.out.println(e2.getMessage());
??????? }
運用六
??? // 事務同時對多個數據庫操作,且不同數據庫要求不同的隔離等級,
?
??????? TestSqlServerDao dao1=new TestSqlServerDao();
??????? Dao2 dao2=new Dao2();
?
??????? Transaction tran=new Transaction();
??????? try{
??????????? tran.begin();
??????????? ......
??????????? tran.call(dao1,java.sql.Connection.TRANSACTION_READ_UNCOMMITTED).update(...);
??????????? tran.call(dao2,java.sql.Connection.TRANSACTION_NONE)).remove(...);
??????????? ......
??????????? tran.commit();
??????? }catch(Exception e2){
??????????? try {
??????????????? tran.rollback();
??????????? } catch (Exception ex) {
??????????? }
??????????? System.out.println(e2.getMessage());
??????? }
?
posted on 2006-08-15 17:30
newxy新坐標 閱讀(408)
評論(0) 編輯 收藏