想搭一个基础的框架,不想用spring和hibernate那些东西....
自己写连接池连接(连接池代码就不想多说,主要是能获取一个connection对象).
想自己写事务处理.service和dao层尽量解耦合(所有的关于业务的事务处理都在service层解决,dao层只做数据库操作)
[code="java"]
import java.io.*;
import java.util.*;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
import javax.transaction.*;
import java.sql.ResultSet;
/**基类**/
public class BaseDAL implements java.io.Serializable
{
protected java.sql.Connection myConn=null;
public java.sql.Statement stmt = null ;
protected java.sql.PreparedStatement pstmt = null;
//public java.sql.ResultSet rs = null;
private javax.sql.DataSource ds =null;
private javax.transaction.UserTransaction transaction =null;
private Context ctx =null;
public int makeTrans=0; //表示是否启动了事务,为0表示没有启动事务,1表示有启动事务
public int connCount =0; //表示数据库连接的次数,每调用一次Connection,加1,每调用一次Disconnect,减1
protected java.lang.String JNDIName;
public BaseDAL() throws Exception
{
try
{
JNDIName ="jdbc/TripDataSource";
ctx =new InitialContext();
}
catch (Exception e)
{
throw e;
}
}
public void setTransactionTimeOut(int time)
{
try
{
this.transaction.setTransactionTimeout(time);
}
catch (Exception e)
{
}
}
/**修改JNDIName**/
public void setJNDIName(String JNDIName)
{
this.JNDIName = JNDIName;
myConn = null;
}
/**事务创建**/
public void begin() throws Exception
{
try
{
if (transaction == null)
{
transaction =(javax.transaction.UserTransaction)
ctx.lookup("javax.transaction.UserTransaction");
transaction.setTransactionTimeout(120);
}
if (ds==null)
{
ds = (javax.sql.DataSource) ctx.lookup(JNDIName);
}
//获得当前的事务状态,如果不为0,表示当前没有事务在处理
int tranStatus = transaction.getStatus();
if ( tranStatus != 0)
{
//启动一个事务,记录当前有事务处理
makeTrans = 1;
transaction.begin();
}
}
catch( Exception E)
{
throw E;
}
}
/**事务提交**/
public void commit() throws Exception
{
try
{
//如果当前有提交事务
if ( makeTrans != 0)
{
transaction.commit();
makeTrans = 0;
}
}
catch(Exception E)
{
throw E;
}
}
/**事务回滚**/
public void rollback() throws Exception
{
try
{
//如果当前有提交事务
if ( makeTrans != 0)
{
transaction.rollback();
makeTrans = 0;
}
}
catch(Exception E)
{
throw E;
}
}
/**连接数据库**/
protected void connection() throws Exception
{
try
{
if (ds==null)
{
ds = (javax.sql.DataSource) ctx.lookup(JNDIName);
}
//如果连接计数为0,连接数据库
if (connCount==0)
{
myConn = ds.getConnection();
stmt = myConn.createStatement();
}
connCount ++;
}
catch (Exception E)
{
throw E;
}
}
/**断开数据库**/
protected void disConnection() throws Exception
{
try
{
connCount --;
if (connCount == 0)
{
try
{
if (stmt != null)
stmt.close();
myConn.close();
}
catch ( Exception e)
{
e.printStackTrace();
}
}
}
catch (Exception E)
{
throw E;
}
}
/**创建事务,包括数据连接**/
public void transactionBegin() throws Exception
{
begin();
connection();
}
/**事务提交,包括断开数据库**/
public void transactionCommit() throws Exception
{
disConnection();
commit();
}
/**事务回滚、包括断开数据库**/
public void transactionRollback() throws Exception
{
disConnection();
rollback();
}
public void showmessage(String str)
{
}
[/code]
上面是一个事务处理的基类,以前写的dao都是继承这个基类再实现一个接口
[code="java"]
this.transactionBegin();
/**
处理SQL,如果有多样执行的话,多条SQL涉及多张表
**/
this.stmt.executeUpdate(sql);
this.transactionCommit();
失败
this.transactionRollback();
[/code]
以前写的service是使用实现接口的dao来访问dao层
现在脑袋进入死锁状态,想不出,该如何解开这块事物,也就是把事务处理放在service..
怎么设计,该使用什么事务处理..
[b]问题补充:[/b]
如果用spring和hibernate我就自己去看书了..希望各位别在用框架回答了...
[b]问题补充:[/b]
谢谢抛出异常的爱
大概意思我明白..
[code="java"]
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Object result = null;
try {
//事务开始
begin();
result = method.invoke(this.delegate, args);
//执行原来的方法之后记录日志
commit(); //事务结束
} catch (Exception e) {
rollback();
e.printStackTrace();
}finally{
logger.error("finally运行");
}
//返回方法返回值给调用者
return result;
}
public static void main(String arg[]) throws SQLException, InterruptedException{
MixUpper mx = (MixUpper) new DynaProxyHello().bind(new Tmalple());
mx.sonMother();
mx.updateFather();
}
[/code]
这样当mx.sonMonther()的时候就执行一次事务.
mx.updateFather()的时候又执行一次事务,如果updateFather的时候失败,不会回滚回mx.sonMonther()
还是说我理解错误
[b]问题补充:[/b]
如果涉及到多张表操作..
因为我想,每张表都有自己的dao处理方式,不会耦合在一起....
如何用一个代理类实现多个代理方法
[b]问题补充:[/b]
尝试了下代理,好象没什么效果..可能是我写错了
代理类
[code="java"]
import javax.transaction.UserTransaction;
import javax.naming.NamingException;
import javax.naming.InitialContext;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.InvocationHandler;
import javax.naming.Context;
public class DynaProxyTransaction
implements InvocationHandler {
private Object object;
public Object bind(Object obj) {
this.object = obj;
return Proxy.newProxyInstance(this.object.getClass().getClassLoader(),
this.object.getClass().getInterfaces(), this);
}
public Object invoke(Object proxy, Method method, Object[] args) throws
Throwable {
Object result = null;
InitialContext ic = null;
UserTransaction ut = null;
ic = getContext();
ut = getUserTransaction();
try {
System.out.println("事务开始");
ut.begin();
// JVM通过这条语句执行原来的方法(反射机制)
result = method.invoke(this.object, args);
ut.commit();
System.out.println("事务提交");
}
catch (Exception e) {
System.out.println("事务回滚");
ut.rollback();
e.printStackTrace();
}
// 返回方法返回值给调用者
return result;
}
private InitialContext getContext() {
InitialContext ic = null;
try {
ic = new InitialContext();
}
catch (NamingException e) {
e.printStackTrace();
}
return ic;
}
private UserTransaction getUserTransaction() {
UserTransaction ut = null;
try {
ut = (UserTransaction) getContext().lookup(
"javax.transaction.UserTransaction");
}
catch (NamingException e) {
e.printStackTrace();
}
return ut;
}
}
[/code]
dao层
[code="java"]
public class AdminDALImpl
implements AdminDAL {
Connection con = null;
private Context ctx = null;
private javax.sql.DataSource ds = null;
public AdminDALImpl() {
String JNDIName = "***";
try {
ctx = new InitialContext();
ds = (javax.sql.DataSource) ctx.lookup(JNDIName);
try {
con = ds.getConnection();
}
catch (SQLException ex1) {
ex1.getMessage();
}
}
catch (NamingException ex) {
ex.getMessage();
}
}
public void saveBean(String name, String pwd) throws Exception {
java.sql.Statement st = null;
String sql = "insert into t_admin (name,pwd) values ('" + name
+ "','" + pwd + "')";
try {
st = con.createStatement();
st.executeUpdate(sql);
}
catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
throw new Exception(e.getMessage());
}
finally {
con.close();
st.close();
}
}
}
[/code]
dao层
[code="java"]
public class TestDALImpl
implements TestDAL {
Connection con = null;
private Context ctx = null;
private javax.sql.DataSource ds = null;
public TestDALImpl() {
String JNDIName = "***";
try {
ctx = new InitialContext();
ds = (javax.sql.DataSource) ctx.lookup(JNDIName);
try {
con = ds.getConnection();
}
catch (SQLException ex1) {
ex1.getMessage();
}
}
catch (NamingException ex) {
ex.getMessage();
}
}
public void saveBean(String id, String name) throws Exception {
java.sql.Statement st = null;
String sql = "insert into test (id,name) values ('" +
id
+ "','" + name + "')";
try {
st = con.createStatement();
st.executeUpdate(sql);
}
catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
throw new Exception(e.getMessage());
}
finally {
st.close();
con.close();
}
}
}
[/code]
服务层
[code="java"]
public class TestBusinessImpl implements TestBusiness{
public TestBusinessImpl() {
}
public void saveTest() throws Exception {
AdminDAL adminDal = new AdminDALImpl();
TestDAL testDal = new TestDALImpl();
adminDal.saveBean("abcd", "abcd");
testDal.saveBean("test","testtesttesttesttesttesttesttesttesttesttesttesttesttesttesttest");
}
}
[/code]
servlet 类
[code="java"]
public class TestServlet
extends HttpServlet {
public TestServlet() {
}
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException,
IOException {
System.out.println("**进入servlet**");
TestBusiness business = (TestBusiness)new DynaProxyTransaction().bind(new TestBusinessImpl());
try {
business.saveTest();
}
catch (Exception ex) {
ex.getMessage();
}
}
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException,
IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
[/code]
随便搭了一个平台,接口类我就没写了...
试了好多次..保存test的时候执行SQL是错误的,应该执行事务回滚.第一条好是插入进去了
sdh5724说的Anotation还没去研究
谢谢
[b]问题补充:[/b]
可能你们没看到我这样写是错误的...
我也知道没关联上.但是我不知道该如何关联上...
[b]问题补充:[/b]
既然决定发这个贴,就不怕受打击了...
但是还是请多多指教.既然不需要.为什么希望指明点,对事务处理这块碰到的比较少..
[b]问题补充:[/b]
[quote]
单一数据库, Connetion就能完成事务了, 也就是所说的数据库自身的事务管理:)
[/quote]
你是说jdbc自带的事务处理?
con.setAutoCommit(false);设置为手动提交?
那是如何让dao只执行数据库操作
难道把connection做参数传进去?
[b]问题补充:[/b]
我只是想理解这块的设计方式,如何设计是比较OK的,代码如何写才是比较好的.如何解决类似这样的问题..
抛出异常的爱让我知道可以用代理模式(很早以前就看过代理,一直没想到该用在什么地方)
sdh5724也让我知道我还有好都东西搞的乱七八糟,现在恶补中...
谢谢几位,
大家有什么意见还可以提,这并不是说要解决具体什么问题,只是一个想了解设计
思路来彻底的解开这耦合.我会准时结帖...
备注:Anotation应该是Annotation