springにおけるプログラミング的な事務

6360 ワード

ここではまず、JDBCがどのように事務管理を実現するかを紹介します.まず、事務の原子的実現を見てみます.JDBCでは、ConnectionのsetAutoCommit()方法を操作して、falseパラメータを与えて、一連のSQL文を下達した後、自分でConnectionのcomit()を実行して変更を送出します.もし中間にエラーが発生したら、rollback()を実行して全ての実行をキャンセルします.例えば:
 
try { 
..... 
connection.setAutoCommit(false); 
..... 
//    SQL   

connection.commit(); 
} catch(SQLException) { 
//     ,       

connection.rollback(); 
}
 SpringでJDBCの事務管理をカプセル化し、Spring事務管理の抽象的なポイントはorg.springframe ebork.trantions.PlatformTransation Managerインターフェースの実現である.
 
 
public interface PlatformTransactionManager { 
TransactionStatus getTransaction(TransactionDefinition 
definition) throws TransactionException; 
void commit(TransactionStatus status) 
throws TransactionException; 
void rollback(TransactionStatus status) 
throws TransactionException; 
}
Platform Transaction Managerインターフェースには、DataSourceTransactionager、Hibernation Transation Manager、JdoTransaction-Manager、JtaTransation Managerなど、Platform Transation Managerインターフェースや様々な技術に依存することで、Springは、事務管理者が一致してプログラムを開発することができます.異なる事務管理技術を使用しても.
Transaction ExceptionはUnicheced Exceptionです.事務の失敗はいつも致命的なエラーです.Springはあなたに必ず処理するように強制しないで、異常を捉えるかどうかを自分で選択させます.
get Transaction()方法は、Transaction Definitionオブジェクトを1つのTransaction Stortsオブジェクトに往復送信する方法であり、Transaction Definitionインターフェースの例に従って、トランザクションの分離度(Isolation level)、伝播行為(Propagation behavior)、タイムアウト(Timeout)、読み取り専用(Read-only)などを定義している.Transactionsは、新しいトランザクションの開始または既存のトランザクションを表しています.これを通じて、トランザクションの実行または調査の状態を制御できます.
public interface TransactionStatus { 
boolean isNewTransaction(); 
void setRollbackOnly(); 
boolean isRollbackOnly(); 
}
 Springはプログラミング式の事務管理(Prograammatic transpation management)と声明式の事務管理を提供します.
プログラミング式の事務管理
プログラミング式の事務管理は、事務の境界を明確にコントロールできます.つまり、事務開始時間、キャンセル操作のタイミング、終了時間などを自分で実現させて、細かい粒度の事務制御ができます.
JDBCプログラミング事務管理Springはプログラミング式の事務管理を実現するための2つの方法を提供しています.1つは直接Platform Transact-Managerを使用して実現します.2つはorg.springframe ewark.transport.Transact-Templateを使用します.
まず、Platform Transation Managerを使う方法を見てみます.ここでは、DataSourceTransation Managerを使って、この前のJdbcTemplatedemoプロジェクトを書き換えることができます.事務管理機能を持たせて、UserDAO類のinsertを修正してモデルを作ります.
package onlyfun.caterpillar; 
import java.util.Iterator; 
import java.util.List; 
import java.util.Map; 
import javax.sql.DataSource; 
import org.springframework.dao.DataAccessException; 
import org.springframework.jdbc.core.JdbcTemplate; 
import org.springframework.jdbc. 
datasource.DataSourceTransactionManager; 
import org.springframework.transaction.TransactionDefinition; 
import org.springframework.transaction.TransactionStatus; 
import org.springframework.transaction. 
support.DefaultTransactionDefinition; 
public class UserDAO implements IUserDAO { 
private DataSourceTransactionManager transactionManager; 
private DefaultTransactionDefinition def; 
private JdbcTemplate jdbcTemplate; 
public void setDataSource(DataSource dataSource) { 
jdbcTemplate = new JdbcTemplate(dataSource); 
transactionManager = 
new DataSourceTransactionManager(dataSource); 
//         

def = new DefaultTransactionDefinition(); 
def.setPropagationBehavior( 
TransactionDefinition.PROPAGATION_REQUIRED); 
} 
public void insert(User user) { 
String name = user.getName(); 
int age = user.getAge().intValue(); 
TransactionStatus status = 
transactionManager.getTransaction(def); 
try { 
jdbcTemplate.update("INSERT INTO user (name,age) " 
+ "VALUES('" + name + "'," + age + ")"); 
//    SQL   ,       

jdbcTemplate.update("INSER INTO user (name,age) " 
+ "VALUES('" + name + "'," + age + ")"); 
} 
catch(DataAccessException e) { 
transactionManager.rollback(status); 
throw e; 
} 
transactionManager.commit(status); 
} 
public User find(Integer id) { 
List rows = jdbcTemplate.queryForList( 
"SELECT * FROM user WHERE id=" + id.intValue()); 
Iterator it = rows.iterator(); 
if(it.hasNext()) { 
Map userMap = (Map) it.next(); 
Integer i = new Integer( 
userMap.get("id").toString()); 
String name = userMap.get("name").toString(); 
Integer age = new Integer( 
userMap.get("age").toString()); 
User user = new User(); 
user.setId(i); 
user.setName(name); 
user.setAge(age); 
return user; 
} 
return null; 
} 
}
 insert()メソッドにはDataSourceTransation Managerを使用して事務管理を行い、異常が発生したらcatchブロックに事務を行うRollbackがinsert()メソッドに故意に誤ったSQLを書き込むので、実際のデータはデータベースに保存されません.
MySQLデータベースを用いた事務処理には、サポートトランザクションのテーブルタイプ、例えばInnoDBのテーブルタイプが必要です.ここでテーブルを作るためのSQLは以下の通りです.
CREATE TABLE user ( 
id INT(11) NOT NULL auto_increment PRIMARY KEY, 
name VARCHAR(100) NOT NULL default '', 
age INT 
) TYPE = InnoDB;
 もう一つのプログラミングされたトランザクション管理を実現する方法は、Transaction Templateを使用することであり、Transaction Managerの一例が必要であり、以下のように示されている.
TransactionTemplate transactionTemplate = 
new TransactionTemplate(transactionManager); 
... 
transactionTemplate.execute(new TransactionCallback() { 
public Object doInTransaction(TransactionStatus status) { 
return jdbcTemplate.update("INSERT INTO user (name,age) " 
+ "VALUES('" + name + "'," + age + ")"); 
} 
});
 異常が発生したらRollbackを行います.そうでなければ、トランザクションを提出します.もしフィードバック値がないなら、TransactCallback Without Resoultを使ってもいいです.
 
transactionTemplate.execute( 
new TransactionCallbackWithoutResult() { 
public void doInTransactionWithoutResult( 
TransactionStatus status) { 
. ... 
} 
});
住所:http://developer.51cto.com/art/200906/127430.htm