multithreading - GORM 实例对象线程安全
问题描述
假设我有以下域类。具有多对一关系的 anEmployee
和 aCompany
class Employee {
String id
String firstName
String lastName
String email
Company company
static mapping = {
table name: "employee"
id column: "employee_id", generator:"assigned"
version false
}
}
class Company {
String id
String name
static hasMany = [employees:Employee]
static mapping = {
table name: "company"
id column: "company_id", generator:"assigned"
autoImport false
version false
}
}
我想做的是Company
从数据库中获取一个对象,然后产生多个线程来Employees
为公司创建。但是,我不确定该Company
对象是否是线程安全的。
例如:
public void createEmployees(companyId, employees){
// Find the new created company - this is on the main thread
Company company = Company.findById(companyId) // Is company thread safe?
def lines = parseEmployees(employeeFile) // parses info about each employee that will later be used to create employee objects
ExecutorService executor = Executors.newFixedThreadPool(10)
List futures = new ArrayList()
lines.each { line ->
Future future = executor.submit(new Callable() {
public def call() throws Exception {
def employee = saveEmployee(line, company) // Is the company object thread safe here?
return employee
}
});
futures.add(future)
}
executor.shutdown()
for(Future future : futures){
def employee = future.get()
println employee
}
}
public Employee saveEmployee(line, company) {
Employee employee = new Employee()
employee.firstName = line.firstName
employee.lastName = line.lastName
employee.email = employee.email
employee.id = line.id
employee.company = company // thread safe?
employee.save()
}
同样,我不确定Company
传递给该saveEmployee
方法的 Hibernate 托管对象是否是线程安全的。我的理解是,每个Thread
人Executor
都有自己的 Hibernate Session,它不是线程安全的。我想我可能需要调用merge
或attach
在Company
对象上,但似乎我不需要。一切似乎都很好,但在多线程方面可能很难说。
解决方案
在您提供的示例中,Company
传递的对象没有被修改,因此它是否是线程安全的并不重要。(但不是;如果您在多个线程中对其进行更改,您将获得 StaleObjectStateExceptions。)
您的Company
hasMany
员工,在您当前的映射中,引用实际上存储在Employee
(可能是 company_id 字段)中。由于在将对象与员工关联时,您并没有在技术上修改Company
对象,因此这不会导致问题。
有很多方法可以确认这一点(因为很难测试所有奇怪的线程边缘情况!)但在我看来,最简单的方法可能是确认添加新员工时对象上的version
字段Company
不会增加。如果这没有增加,您可以确信它没有被修改,因此线程在这里不会发挥作用。
推荐阅读
- laravel - Spatie 权限与另一个模型和 jwt 与用户不起作用
- java - 如何让 EditText 过滤负数和正数之间的数字
- laravel - 如何在 Laravel 日志中显示用户数据(使用 sanctum auth)
- python - 为什么扩展 docker-airflow 映像,使我的调度程序容器不健康?
- matrix - 如何同情行列式列表
- javascript - 在某些设备(VueJS、iOS / Android)上未触发模糊事件
- python - 需要 Python 正则表达式帮助,多行正则表达式
- laravel - 如何删除超过一小时的公共存储文件?
- arrays - 如何迭代数组以获取下一个元素(2个数组)
- html - 下载为 PDF 文档但用于查看报告时 HTML 中断