Демонстрация красоты LINQ путем написания метода расширения.
/// <summary>
/// Gets the duration of the set union of the specified intervals.
/// </summary>
/// <param name="timeLapses">Sequence of <see cref="TimeLapse"/> ordered by <see cref="TimeLapse.StartTime"/>.</param>
public static TimeSpan UnionDurations(this IEnumerable<TimeLapse> timeLapses)
{
using (var e = timeLapses.GetEnumerator())
{
if (!e.MoveNext()) // no items, no duration
return TimeSpan.Zero;
var prev = e.Current;
var total = prev.EndTime - prev.StartTime; // set running total to duration of 1st interval
while (e.MoveNext())
{
var curr = e.Current;
if (curr.StartTime < prev.StartTime) throw new Exception($"{nameof(timeLapses)} are not in ascending {nameof(TimeLapse.StartTime)} order.");
var increase = curr.EndTime - (curr.StartTime > prev.EndTime ? curr.StartTime : prev.EndTime);
if (increase <= TimeSpan.Zero) continue;
total += increase;
prev = curr;
}
return total;
}
}
Тестовый код:
var input = new Dictionary<string, IList<TimeLapse>>
{
{
"A",
new[]
{
new TimeLapse{ StartTime = new DateTime(2019, 1, 17, 0, 0, 0), EndTime = new DateTime(2019, 1, 17, 3, 0, 0)},
new TimeLapse{ StartTime = new DateTime(2019, 1, 17, 1, 0, 0), EndTime = new DateTime(2019, 1, 17, 2, 0, 0)},
new TimeLapse{ StartTime = new DateTime(2019, 1, 17, 1, 0, 0), EndTime = new DateTime(2019, 1, 17, 4, 0, 0)},
new TimeLapse{ StartTime = new DateTime(2019, 1, 17, 5, 0, 0), EndTime = new DateTime(2019, 1, 17, 7, 0, 0)}
}
},
{
"B",
new TimeLapse [0]
}
};
var result = input
.Select(kv => new
{
Device = kv.Key,
FaultyDuration = kv.Value
// .OrderBy(tl => tl.StartTime) // this line can be removed if already ordered by StartTime
.UnionDurations()
})
.ToList();
// { Device = A, FaultyDuration = 06:00:00 }
// { Device = B, FaultyDuration = 00:00:00 }
Убедитесь, что у вас есть активная транзакция при выполнении этого оператора. Если вы используете JPA, используйте EntityManager.getTransaction (). Begin (). Это предполагает, что вы используете JPA вне области транзакции JTA.
Если вы запускаете приложение в контейнере с поддержкой JTA, вы также можете использовать JTA UserTransaction для управления транзакциями.
То же самое происходило со мной при использовании весны 3.0.0 / 3.0.3. Данные сохранялись в MySQL из JUnit, но не с сервера Tomcat. После такой большой работы я отказался от RESOURCE_LOCAL для JTA.
Это сработало для меня http://erich.soomsam.net/2007/04/24/spring-jpa-and-jta-with-hibernate-and-jotm/ Используется JTA и зависит на JOTM.
Для JBoss 4.0 и Hibernate я исправил эту проблему, добавив некоторые свойства менеджера транзакций в мое определение EntityManagerFactoryBean
:
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="xaDs" />
<property name="jpaProperties">
<props>
<prop key="hibernate.transaction.factory_class">org.hibernate.transaction.JTATransactionFactory
</prop>
<prop key="hibernate.transaction.manager_lookup_class">org.hibernate.transaction.JBossTransactionManagerLookup
</prop>
</props>
</property>
Я нашел солутон в этом Тема на форуме .
Пожалуйста, убедитесь, что ваш метод обработчика объявлен как публичный
@Transactional
@RequestMapping('/test')
public String doTest() {
// do your stuff here
return 'testview';
}
Убедитесь, что ваша конфигурация пружин включает следующее строка:
режим
может быть либо прокси , либо аспектом и диспетчер транзакций
должен указывать на вашего диспетчера транзакций.