要实现对数据库的操作,离不开数据源(datasource)或者连接(connection),但是通常来说对数据库的操作都应该放在dao中,而dao又不应该与应用服务器相关联,所以一般都使用连接(connection)。现在我们这里就有一个问题了,怎么在拦截器中获得连接。我想可以通过两种方式获得:
在分别讨论这两种方法之前,我们需要先讨论一下在处理数据库的时候的异常的处理。我这里做了一个transactionexception继承至runtimeexception然后在拦截器里面抛出,再又应用框架处理这个异常。下面试这个类的代码:
public class transactionexception extends runtimeexception {
private throwable superexception;
private string mymessage;
public transactionexception(throwable throwable){
super(throwable);
this.superexception = throwable;
}
public transactionexception(throwable throwable,string message){
super(message,throwable);
this.superexception = throwable;
this.mymessage = message;
}
/**
* @return returns the mymessage.
*/
public string getmessage() {
return mymessage;
}
/**
* @return returns the superexception.
*/
public throwable getsuperexception() {
return superexception;
}
/**
* @param mymessage the mymessage to set.
*/
public void setmymessage(string message) {
this.mymessage = message;
}
/**
* @param superexception the superexception to set.
*/
public void setsuperexception(throwable superexception) {
this.superexception = superexception;
}
}
1) 通过方法的第一个参数传进去
l dao
import java.sql.connection;
public class testdao {
public void inserta(connection con,string a,string b,……){
…………………………………………
一系列操作
…………………………………………
}
public string querya(connection con,…….){
…………………………………………
一系列操作
…………………………………………
}
public void updatea(connection con,…….){
…………………………………………
一系列操作
…………………………………………
}
}
l 拦截器
import java.sql.connection;
import java.sql.sqlexception;
import java.util.arraylist;
import java.util.list;
public class transactioninterceptor implements interceptor {
public void before(invokejniinfo invinfo) {
if(isneedtransactions(invinfo)){
connection conn = (connection) invinfo.getargs()[0];
try {
conn.setautocommit(false);
} catch (sqlexception e) {
throw new transactionexception(e);
}
}
}
public void after(invokejniinfo invinfo) {
if(isneedtransactions(invinfo)){
connection conn = (connection) invinfo.getargs()[0];
try {
conn.commit();
} catch (sqlexception e) {
throw new transactionexception(e);
}finally{
if(conn != null){
try {
conn.close();
} catch (sqlexception e) {
throw new transactionexception(e,"close connection is failure!");
}
}
}
}
}
public void exceptionthrow(invokejniinfo invinfo) {
if(isneedtransactions(invinfo)){
connection conn = (connection) invinfo.getargs()[0];
try {
conn.rollback();
} catch (sqlexception e) {
throw new transactionexception(e);
}finally{
if(conn != null){
try {
conn.close();
} catch (sqlexception e) {
throw new transactionexception(e,"close connection is failure!");
}
}
}
}
}
private list getneedtransaction(){
list needtransactions = new arraylist();
needtransactions.add("insert");
needtransactions.add("update");
return needtransactions;
}
private boolean isneedtransactions(invokejniinfo invinfo){
string needtransaction = "";
list needtransactions = getneedtransaction();
for(int i = 0;i
if(invinfo.getmethod().getname().startswith(needtransaction)){
return true;
}
}
return false;
}
}
需要注意的是:getneedtransaction就是需要进行事务处理的方法的开头,这个方法可以写成一个从配置文件里面去读,这里我就写死在里面了。只是对insert和update开头的方法进行事务控制。
2) 将connection对象放在threadlocal中
l connectionutil类:
import java.sql.connection;
public final class connectionutil {
private static threadlocal connections = new threadlocal();
public static connection getconnection(){
connection conn = null;
conn = (connection) connections.get();
if(conn == null){
conn = getrealconnection();
connections.set(conn);
}
return conn;
}
public static void realseconnection(connection conn){
connections.set(null);
}
private static connection getrealconnection() {
实现自己获取连接的代码
return null;
}
}
l dao类
public class testdao {
public void inserta(string a,string b){
connection conn = getconnection();
…………………………………………
一系列操作
…………………………………………
}
public string querya(connection con,…….){
connection conn = getconnection();
…………………………………………
一系列操作
…………………………………………
}
public void updatea(connection con,…….){
connection conn = getconnection();
…………………………………………
一系列操作
…………………………………………
}
private connection getconnection(){
return connectionutil.getconnection();
}
}
l 拦截器
import java.sql.connection;
import java.sql.sqlexception;
import java.util.arraylist;
import java.util.list;
public class transactioninterceptor implements interceptor {
public void before(invokejniinfo invinfo) {
if(isneedtransactions(invinfo)){
connection conn = getconnection();
try {
conn.setautocommit(false);
} catch (sqlexception e) {
throw new transactionexception(e);
}
}
}
public void after(invokejniinfo invinfo) {
if(isneedtransactions(invinfo)){
connection conn = getconnection();
try {
conn.commit();
} catch (sqlexception e) {
throw new transactionexception(e);
}finally{
if(conn != null){
try {
conn.close();
releaseconnection(conn);
} catch (sqlexception e) {
throw new transactionexception(e,"close connection is failure!");
}
}
}
}
}
public void exceptionthrow(invokejniinfo invinfo) {
if(isneedtransactions(invinfo)){
connection conn = getconnection();
try {
conn.rollback();
} catch (sqlexception e) {
throw new transactionexception(e);
}finally{
if(conn != null){
try {
conn.close();
releaseconnection(conn);
} catch (sqlexception e) {
throw new transactionexception(e,"close connection is failure!");
}
}
}
}
}
private connection getconnection(){
return connectionutil.getconnection();
}
private void releaseconnection(connection conn){
connectionutil.releaseconnection(conn);
}
private list getneedtransaction(){
list needtransactions = new arraylist();
needtransactions.add("insert");
needtransactions.add("update");
return needtransactions;
}
private boolean isneedtransactions(invokejniinfo invinfo){
string needtransaction = "";
list needtransactions = getneedtransaction();
for(int i = 0;i
if(invinfo.getmethod().getname().startswith(needtransaction)){
return true;
}
}
return false;
}
}
最后将这个拦截器添加到aop拦截框架中去,interceptorhandler类中的getintercetors方法中添加一个:
private synchronized list getintercetors(){
if(null == interceptors){
interceptors = new arraylist();
……………………………………
interceptors.add(new transactioninterceptor ());
……………………………………
}
return interceptors;
}
到此全部ok!
闽公网安备 35060202000074号