现在要搭建一个框架 单纯jsp+servlet+javaBean的形式,不采用任何框架数据库操作采用dbUtils,简单的对JDBC进行封装现在有一个疑问:我现在采用service层充当业务逻辑层,dao封装DB相关操作我是在DAO中的每个方法里添加事务还是在service中添加事务呢?最后会在service层中操作不同的表,进行INSERT和UPDATE如何在SERVICE层写事务,如何来写啊怎样更好一些?
没多少分了,大家帮帮忙
没多少分了,大家帮帮忙
解决方案 »
- 求完成的POI读取和生成execl的例子
- 怎么从数据库读取一篇博文 ,然后把值传在一个页面的 txtarea
- Hibernate项目在tomcat服务器中运行一段时间后出错
- Tomcat如何配置即可直接以IP或电脑名访问?
- 关于多对一关联的问题 Exception in thread "main" org.hibernate.exception.SQLGrammarException: Could not execute JDBC batch update
- 新手,struts中超链接怎么设置action mapping.....
- 送什么礼物给老师以表感谢?
- hibernat HQL查询,运行出错
- 谁有用webwork和jsp实现多行记录的删除编辑增加的例子,高分相送
- Jboss-tomcat调试servlet出错误?
- 事务处理的问题
- 找人合作,有兴趣的来。没兴趣就不浪费你时间了。
对dao 出来的资料进行处理
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.HashSet;
import java.util.Set;import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;import net.blogjava.frankiegao123.log.Log;
import net.blogjava.frankiegao123.log.Logger;/**
* 事务代理
* @author frankiegao123
* 2009-10-30 上午10:25:57
*/
public class TransactionProxy {
private static Log log = Logger.getLog(TransactionProxy.class); @SuppressWarnings("unchecked")
public static <T> T delegate(Class<T> clazz, Object obj) {
if(!isRequiredTransaction(obj.getClass())) {
return (T)obj;
}
// 返回代理对象
return (T)Proxy.newProxyInstance(
obj.getClass().getClassLoader(),
obj.getClass().getInterfaces(),
new XAInvocationHandle(obj)
);
}
/**
* 检查某一对象是否需要使用事务,业务方法默认带有事务
* @param obj
* @return
* @author frankiegao123
* 2009-10-30 上午10:26:58
*/
private static boolean isRequiredTransaction(AnnotatedElement obj) {
TransactionAttribute type = obj.getAnnotation(TransactionAttribute.class);
// 为 null 时,说明方法上未标注 TransactionAttribute,这时默认启用事务
if((type == null) || TransactionAttributeType.REQUIRED.equals(type.value())) {
return true;
}
return false;
}
private static void logArguments(Object obj, Method method, Object[] args) {
if(log.isDebugEnabled()) {
if(args == null || args.length == 0) {
return;
}
StringBuilder sb = new StringBuilder();
for(int i = 0; i < args.length; i++) {
if(i > 0) {
sb.append(", ");
}
sb.append(args[i]);
}
}
}
/**
* 使用 JDK 动态代理织入事务处理
* @author frankiegao123
* 2009-10-30 上午11:56:47
*/
private static class XAInvocationHandle implements InvocationHandler {
private Object delegate;
private static Set<String> excludeMethodNames = excludeMethodNames();
public XAInvocationHandle(Object delegate) {
this.delegate = delegate;
} public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
logArguments(delegate, method, args);
if(excludeMethodNames.contains(method.getName())) {
return invokeObjectMethod(proxy, method, args);
}
if(isRequiredTransaction(method)) {
// 需要事务处理
return invokeRequiredTransaction(proxy, method, args);
} else {
// 不需要事务处理
return invokeNeverTransaction(proxy, method, args);
}
}
private Object invokeNeverTransaction(Object proxy, Method method, Object[] args) throws Throwable {
Object obj = null;
EntityManager em = null;
try {
em = JpaEntityManager.bindThreadEntityManager();
obj = method.invoke(delegate, args);
} catch(Throwable e) {
throw e;
} finally {
JpaEntityManager.closeEntityManager(em);
}
return obj;
}
private Object invokeObjectMethod(Object proxy, Method method, Object[] args) throws Throwable {
Object obj = null;
try {
obj = method.invoke(delegate, args);
} catch(Throwable e) {
throw e;
}
return obj;
}
private Object invokeRequiredTransaction(Object proxy, Method method, Object[] args) throws Throwable {
EntityManager em = null;
EntityTransaction transaction = null;
Object obj = null;
try {
em = JpaEntityManager.bindThreadEntityManager();
transaction = em.getTransaction();
transaction.begin();
obj = method.invoke(delegate, args);
transaction.commit();
} catch (Throwable e) {
if(transaction != null && transaction.isActive()) {
transaction.rollback();
}
throw e;
} finally {
JpaEntityManager.closeEntityManager(em);
}
return obj;
}
private static Set<String> excludeMethodNames() {
Method[] methods = Object.class.getMethods();
Set<String> methodNames = new HashSet<String>();
for(int i = 0; i < methods.length; i++) {
methodNames.add(methods[i].getName());
}
return methodNames;
}
}
}import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;import net.blogjava.frankiegao123.log.Log;
import net.blogjava.frankiegao123.log.Logger;/**
* JPA EntityManager 管理工具<br />
*
* 从 EntityManagerFactory 获得 EntityManager 对象并绑定到当前线程中,以便进行事务管理
*
* @author frankiegao123
* 2009-10-30 下午12:16:41
*/
public class JpaEntityManager { private static Log log = Logger.getLog(JpaEntityManager.class); private static EntityManagerFactory factory; /**
* 本地线程容器
*/
private static ThreadLocal<EntityManager> entityManagerThreadBind = new ThreadLocal<EntityManager>(); static {
try {
// 初始化 EntityManagerFactory
factory = Persistence.createEntityManagerFactory(Config.getInstance().getJpaUnitName());
} catch(Exception e) {
log.error("EntityManagerFactory init failed", e);
}
} private JpaEntityManager() {
} /**
* 从当前线程中获得已经绑定在线程上的 EntityManager 对象
* @return
* @author frankiegao123
* 2009-10-30 下午12:35:15
*/
public static synchronized EntityManager getEntityManager(){
EntityManager entityManager = findThreadEntityManager();
if(entityManager == null) {
// 没有绑定时,抛出异常
throw new ThreadEntityManagerException("EntityManager cannot be found from current thread");
}
log.info("find EntityManager: {0} from current thread", entityManager);
return entityManager;
} /**
* 关闭当前线程中的 EntityManager 对象,同时清空当前线程中 EntityManager,便于下次重新绑定执行事务
*
* @param entityManager
* @author frankiegao123
* 2009-10-30 下午12:37:11
*/
public static synchronized void closeEntityManager(EntityManager entityManager) {
EntityManager em = findThreadEntityManager();
log.debug("current thread EntityManager: {0}, parameter EntityManager: {1}", em, entityManager);
if(em == null) {
log.warn("EntityManager object in current thread is null, Using method invoke parameter EntityManager: {0}", entityManager);
em = entityManager;
}
em.close();
em = null;
log.debug("EntityManager object close success");
entityManagerThreadBind.set(null);
log.info("current EntityManager object has been closed and the object in ThreadLocal has been set null");
} /**
* 获得新的 EntityManager 对象,并绑定到当前线程中
*
* @return
* @author frankiegao123
* 2009-10-30 下午12:38:15
*/
public static synchronized EntityManager bindThreadEntityManager() {
EntityManager preEntityManager = findThreadEntityManager();
if(preEntityManager != null) {
// 当前线程中还存在之前没有被处理的 EntityManager 对象
log.warn("pre EntityManager not be closed, EntityManager: {0}", preEntityManager);
closeEntityManager(preEntityManager);
}
EntityManager entityManager = factory.createEntityManager();
setEntityManager(entityManager);
log.debug("EntityManager object was binded to current thread, EntityManager: {0}", entityManager);
return entityManager;
} /**
* 从本地线程中获得 EntityManager 对象
* @return
* @author frankiegao123
* 2009-10-30 下午12:18:44
*/
private static EntityManager findThreadEntityManager() {
return entityManagerThreadBind.get();
} private static void setEntityManager(EntityManager entityManager) {
entityManagerThreadBind.set(entityManager);
}
}还有两个用于标注于业务方法上的事务属性,简单地实现了两个。
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Target(value = { ElementType.METHOD, ElementType.TYPE })
@Retention(value = RetentionPolicy.RUNTIME)
public @interface TransactionAttribute {
TransactionAttributeType value() default TransactionAttributeType.REQUIRED;
}/**
* 事务属性
* @author frankiegao123
* 2009-10-30 上午10:16:06
*/
public enum TransactionAttributeType { /**
* 启用事务
*/
REQUIRED,
/**
* 不启用事务
*/
NEVER
}