- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在使用 JPA EntityListener 做一些额外的审计工作,并使用 @Configurable 将 Spring 管理的 AuditService 注入(inject)我的 AuditEntryListener。 AuditService 生成 AuditEntry 对象的集合。 AuditService 本身是一个 Singleton 范围的 bean,我想将所有 AuditEntry 对象收集在一个公共(public) key 下,然后可以由最外层的服务层(调用持久调用的层调用,进而触发 EntityListener)访问。
我正在考虑使用 Spring 的 TransactionSynchronizationManager 在事务开始时设置一个特定的事务名称(使用 UID() 或其他一些独特的策略),然后使用该名称作为 AuditService 中的键,这将允许我对在该事务中创建的所有 AuditEntry 对象进行分组。
混合声明式和程序化事务管理是否有潜在的麻烦? (虽然我只是设置交易名称)。有没有更好的方法将生成的 AuditEntry 对象与当前事务相关联?此解决方案确实适用于我,但考虑到 TransactionSynchronizationManager 不是为应用程序使用而设计的,我想确保我对它的使用不会导致一些不可预见的问题。
最后,一个相关但不是直接相关的问题:我知道 JPA EntityListeners 的文档警告不要使用当前的 EntityManager,但是如果我确实想用它来区分一个对象和它的持久化自身,我会安全吗在我的 preUpdate() 方法周围使用 @Transactional(propagation=REQUIRES_NEW) 注释?
服务等级
@Transactional
public void create(MyEntity e) {
TransactionSynchronizationManager.setCurrentTransactionName(new UID().toString());
this.em.persist(e);
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
@Override
public void afterCommit() {
Set<AuditEntry> entries = auditService.getAuditEntries(TransactionSynchronizationManager.getCurrentTransactionName());
if(entries != null) {
for(AuditEntry entry : entries) {
//do some stuff....
LOG.info(entry.toString());
}
}
}
});
}
JPA 实体监听器
@Configurable
public class AuditEntryListener {
@Autowired
private AuditService service;
@PreUpdate
public void preUpdate(Object entity) {
service.auditUpdate(TransactionSynchronizationManager.getCurrentTransactionName(), entity);
}
public void setService(AuditService service) {
this.service = service;
}
public AuditService getService() {
return service;
}
审计服务
@Service
public class AuditService {
private Map<String, Set<AuditEntry>> auditEntryMap = new HashMap<String, Set<AuditEntry>>();
public void auditUpdate(String key, Object entity) {
// do some audit work
// add audit entries to map
this.auditEntryMap.get(key).add(ae);
}
}
最佳答案
@菲利普
据我了解,您的要求是:
因此,您很自然地会考虑将 Spring 提供的 TransactionSynchronizationManager 作为存储唯一 token (在本例中为 UID)的工具
使用这种方法要非常小心,TransactionSynchronizationManager 是管理 Spring 所有@Transactional 处理的主要存储助手。在@Transactional 引擎盖下,Spring 正在创建一个适当的 EntityManager,一个适当的同步对象,并使用 TransactionSynchronizationManager 将它们附加到本地线程。
在您的服务类代码中,在您篡改同步对象的 @Transactional 方法中,它最终可能会出现不良行为。
我在这里对@Transactional 的工作原理做了深入的分析,看看:http://doanduyhai.wordpress.com/2011/11/20/spring-transactional-explained/
现在回到您的需求。你可以做的是:
创建一个新注解,比如@Auditable(uid="AuditScenario1") 来注解需要审计的方法,并使用 Spring AOP 拦截这些方法调用并为您管理 Thread 本地处理
示例:
修改后的审计服务
@Service
public class AuditService {
public uidThreadLocal = new ThreadLocal<String>();
...
...
}
可审计注释
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
public @interface Auditable
{
String uid();
}
@Auditable注解的使用
@Auditable(uid="AuditScenario1")
@Transactional
public void myMethod()
{
// Something
}
Spring AOP部分
@Around("execution(public * *(..)) && @annotation(auditableAnnotation))
public Object manageAuditToken(ProceedingJoinPoint jp, Auditable auditableAnnotation)
{
...
...
AuditService.uidThreadLocal.set(auditableAnnotation.uid())...
...
}
希望这会有所帮助。
关于java - 将声明式和编程式事务与 Spring 和 JPA 监听器混合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6346073/
我知道您不应该将打印与 printf,cout 和 wprintf,wcout 混合使用,但是很难找到一个好的答案,为什么以及是否可以绕过它。问题是我使用了一个用 printf 打印的外部库,而我自己
我有以下问题: class A: animal = 'gerbil' def __init__(self): self.result = self.calculate_
我在屏幕上渲染了一堆形状(多边形),我没有使用深度测试。 我只是希望这些形状在绘制在空白区域时使用自己的颜色,并且在绘制到任何非空区域时使用红色像素,即在我的情况下绘制在另一个多边形上。 这里的问题实
我正在尝试在我的 Groovy/Grails 应用程序中混入一个类,我正在使用 the syntax defined in the docs ,但我不断收到错误消息。 我有一个如下所示的域类: cla
我已经找到了 5349574673 个关于 Alpha 混合的页面,但我仍然无法获得想要的结果。我正在尝试使用 opengl 使 gif/png 文件正确显示(具有透明度/半透明度)。 这是我的初始化
我正在尝试记录以下代码,但我似乎无法让 JSDoc 记录该类,甚至无法引用它的存在。 // SomeMixin.js export default superclass => class SomeMi
我有一个类型家族,我想使用 mixin 以模块化方式“丰富”它们。例如: trait Family { self => trait Dog { def dogname:String
我在 Storyboard中有 Collection View 。我在 Storyboard中有一部分单元格,还有我以编程方式创建的部分单元格。我应该在 sizeForItemAtIndexPath
我有一个字节数组,我想更改它的访问方式。这是数组: char bytes[100]; 我想要另一个数组来改变原始数组的访问方式。如果我们可以将引用放在数组中,它看起来像这样: char& bytes_
我需要从 c 文件调用 cpp 方法。我为此编写了这个界面.. cpp文件 extern "C" void C_Test(int p){ Class::CPP_Test(p); } c文件
我的网站有两份 CSS 表,一份是主 CSS,一份是移动 CSS。问题是在移动设备(iPhone、Android)上查看时,两个样式表会混淆。例如,在 iPhone 上查看网站时,会应用主样式表中的某
维护人员的说明:此问题涉及已过时的 bokeh.charts API,该 API 已于多年前删除。有关使用现代 Bokeh 创建各种条形图的信息,请参阅: https://docs.bokeh.org
在下图中,蓝色圆圈仅用于调试目的。我的目标是蓝色圆圈后面的每一层都应该是透明的。我只想保持蓝色圆圈外面的可见。 这是用 swift 编写的代码: let croissantView = UIV
我不是 SQL 专家。我正在使用 SQL Server 2005,我正在尝试弄清楚如何构造一个查询,以便它可以满足多种要求。我有两个表定义如下: Classroom - ID - Departme
原创: 我之前问过这个问题,但我最初的例子有点不完整,我想我现在可以更具体地说明我的问题。 对于上下文,我在旧的 Apple mac 计算机上使用 openGL 3.3 并尝试渲染四边形的重叠层。每个
是否可以将内联(类似 json)映射与同一对象的常规映射定义混合使用? 考虑以下示例: person: {age: 32, weight: 82} name: foo 生成的人应具有给定的年龄、体
假设我有一个 Parent 类,它有四个字段 A、B、C 和 D,这样 C 和 D 可以选择传递或使用默认实现进行初始化: open class Parent(val a: A, val b: B,
我正在使用 symphony (1.4) 框架在 PHP 中开发一个 Web 应用程序。该代码使用 SVN 进行版本控制。在此网络应用程序中,我们所有客户共享一个共同的基础,以及一些专门为每个客户创建
我想使用两个小部件(一次一个)作为我的应用程序的基础/背景,上面有一个 QML UI 和一个无边框窗口。它应该看起来像这样: 基于 OpenGL 的扫描组件 通过窗口句柄操作的 3D 可视化组件 多个
我们有一个混合的 AngularJS/Angular 8 应用程序,并且我们不断遇到来自不同版本框架的组件之间的变化检测非常慢的问题。到目前为止,我们只在 Angular 组件中使用 AngularJ
我是一名优秀的程序员,十分优秀!