锁定从Singleton EJB到无状态会话Bean的传播(Lock propagation from Singleton EJB to Stateless Session Bean)
我有这个EJB Singleton(EJB 3.1):
@Singleton @Startup @Lock(LockType.READ) public class SingletonExample { @EJB private StatelessSBExample stlsb; ... @Schedule(..........., persistent = false) @AccessTimeout(0) @Lock(LockType.READ) public void call1SB() { stlsb.doSomething(); } @Schedule(..........., persistent = false) @AccessTimeout(0) @Lock(LockType.READ) public void call2SB() { stlsb.doSomething(); } }
我的bean是一个传统的EJB无状态会话Bean:
@Stateless public class StatelessSBExample { public void domSomething() { ... } }
用visualvm监控,我意识到一些线程正在积累。 该应用程序以Thread Live Peak = 92开始,现在为102,并且正在增加。 在VisualVM线程中,我有几个状态为“Park”和“Wait”的线程。 在我的线程转储中,我有很多:
"Thread-42" - Thread t@190 java.lang.Thread.State: WAITING at sun.misc.Unsafe.park(Native Method) - parking to wait for <71bfce05> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175) at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039) at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1088) at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809) at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745) Locked ownable synchronizers: - None
和
"__ejb-thread-pool13" - Thread t@130 java.lang.Thread.State: WAITING at sun.misc.Unsafe.park(Native Method) - parking to wait for <5cfe398e> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175) at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039) at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442) at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745) Locked ownable synchronizers: - None
我的错在哪里? 我只想执行call1SB(),如果它正在运行,不会再次执行此方法(与call2SB相同)
PS我不能使用LockType.WRITE,因为我想同时执行call1SB()和call2SB()(我没有属性在我的Singleton ..只有方法)
I have this EJB Singleton (EJB 3.1):
@Singleton @Startup @Lock(LockType.READ) public class SingletonExample { @EJB private StatelessSBExample stlsb; ... @Schedule(..........., persistent = false) @AccessTimeout(0) @Lock(LockType.READ) public void call1SB() { stlsb.doSomething(); } @Schedule(..........., persistent = false) @AccessTimeout(0) @Lock(LockType.READ) public void call2SB() { stlsb.doSomething(); } }
My bean is a tradicional EJB Stateless Session Bean:
@Stateless public class StatelessSBExample { public void domSomething() { ... } }
Monitoring with visualvm, I realized that some threads are accumulating. The application started with Thread Live Peak = 92 and is now 102. And it is increasing. In VisualVM Threads, I have several threads with the status "Park" and "Wait". In my Thread Dump I have a lot:
"Thread-42" - Thread t@190 java.lang.Thread.State: WAITING at sun.misc.Unsafe.park(Native Method) - parking to wait for <71bfce05> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175) at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039) at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1088) at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809) at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745) Locked ownable synchronizers: - None
and
"__ejb-thread-pool13" - Thread t@130 java.lang.Thread.State: WAITING at sun.misc.Unsafe.park(Native Method) - parking to wait for <5cfe398e> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175) at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039) at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442) at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745) Locked ownable synchronizers: - None
Where is my fault? I just want to execute call1SB() and, if it is running, doesnt execute this method again (the same to call2SB)
P.S. I can not use LockType.WRITE because I want to execute call1SB() and call2SB() at the same time (I dont have attributes in my Singleton.. only methods)
原文:https://stackoverflow.com/questions/40872709
最满意答案
如果你看看文档(http://api.rubyonrails.org/classes/ActiveRecord/Migration.html),你会看到add_index是
add_index(table_name, column_names, options)
所以编写你的代码如下:
def up add_index(:events,[:schedule_id, :day , :start_time],name: "event_schedule_by_day_and_time_index") end
应该是你想要的。 选项出现在列ID后面。
if you look at the docs (http://api.rubyonrails.org/classes/ActiveRecord/Migration.html) you will see that add_index is
add_index(table_name, column_names, options)
so writing your code as follows:
def up add_index(:events,[:schedule_id, :day , :start_time],name: "event_schedule_by_day_and_time_index") end
should be what you want. The options come after the column ids.
相关问答
更多-
您也可以在迁移中执行任意SQL。 我们有一些帮助器方法可以将外键添加到我们的表中: def add_foreign_key(from_table, from_column, to_table) constraint_name = "fk_#{from_table}_#{from_column}" execute %{alter table #{from_table} add constraint #{constraint_name} foreign ...
-
使用带有rails迁移的mysql创建多列独特索引(Create multi column distinct index using mysql with rails migration)[2023-07-10]
它显然是错误的( Duplicate entry '5-9' )你的数据不是唯一的,所以你不能在那里添加这样的索引 Its clearly in error (Duplicate entry '5-9') that your data is not unique so You can't add such index there -
我会说,你有正确的解决方案,因为索引将需要重新生成,因此为什么没有update_index 。 I would say that you have the correct solution there as the index will need to be regenerated, hence why there is no update_index.
-
您可以运行另一个迁移,仅用于索引: class AddIndexToTable < ActiveRecord::Migration def change add_index :table, :user_id end end You can run another migration, just for the index: class AddIndexToTable < ActiveRecord::Migration def change add_index :table, : ...
-
如何使列独特,并在Ruby on Rails迁移中进行索引?(How do I make a column unique and index it in a Ruby on Rails migration?)[2022-07-13]
简短的答案: add_index :table_name, :column_name, unique: true 要一起索引多个列,您传递列名称数组而不是单个列名称, add_index :table_name, [:column_name_a, :column_name_b], unique: true 为了更精细的粒度控制,有一个执行直SQL的“ execute ”方法。 而已! 如果您正在做此替代常规旧型号验证,请检查它是如何工作的。 我不知道向用户报告的错误将会很好。 你可以随时做这两个。 Th ... -
多列索引的Rails迁移 - 如何命名索引?(Rails migration for multi-column index - how can I name the index?)[2023-04-02]
如果你看看文档(http://api.rubyonrails.org/classes/ActiveRecord/Migration.html),你会看到add_index是add_index(table_name, column_names, options) 所以编写你的代码如下: def up add_index(:events,[:schedule_id, :day , :start_time],name: "event_schedule_by_day_and_time_index") ... -
m.add_unique_index([:long_column, :super_long_column], 'shortened_index_name') 链接到#add_unique_index的LHM文档 m.add_unique_index([:long_column, :super_long_column], 'shortened_index_name') Link to LHM docs for #add_unique_index
-
只需将语法更改为以下方式将新列添加到索引即可: ALTER table `books` DROP INDEX theindex; ALTER table `books` ADD INDEX theindex (`date`, `time`); Just change the syntax to the below way to add new columns to the index: ALTER table `books` DROP INDEX theindex; ALTER table `books` ...
-
这在很大程度上取决于存储在表中的数据。 这是一个带有单个表的数据库,其查询仅针对记录的唯一ID / PK运行吗? 如果是这样,那么只需索引单个列,即id列。 如果不是,它可能要求跨多个列进行索引。 这是一个案例问题,不能一概而论。 索引可能非常棘手,过度索引实际上可能会损害性能(特别是在插入和更新时)。 在mysql中广泛使用“EXPLAIN”语句来查看索引更改如何影响mysql实际查询数据的方式。 This is something that depends heavily on the data sto ...
-
Rails不会使用仅用于索引的内容自动生成迁移 使用以下命令编辑生成的迁移: class AddIndexToProductImages < ActiveRecord::Migration def change add_index :product_images, :item_id end end Rails will not autogenerate the migration with content just for index Edit the generated migratio ...