`
234390216
  • 浏览: 10247338 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
博客专栏
A5ee55b9-a463-3d09-9c78-0c0cf33198cd
Oracle基础
浏览量:463286
Ad26f909-6440-35a9-b4e9-9aea825bd38e
springMVC介绍
浏览量:1776811
Ce363057-ae4d-3ee1-bb46-e7b51a722a4b
Mybatis简介
浏览量:1399505
Bdeb91ad-cf8a-3fe9-942a-3710073b4000
Spring整合JMS
浏览量:395341
5cbbde67-7cd5-313c-95c2-4185389601e7
Ehcache简介
浏览量:680463
Cc1c0708-ccc2-3d20-ba47-d40e04440682
Cas简介
浏览量:531552
51592fc3-854c-34f4-9eff-cb82d993ab3a
Spring Securi...
浏览量:1186082
23e1c30e-ef8c-3702-aa3c-e83277ffca91
Spring基础知识
浏览量:470158
4af1c81c-eb9d-365f-b759-07685a32156e
Spring Aop介绍
浏览量:151821
2f926891-9e7a-3ce2-a074-3acb2aaf2584
JAXB简介
浏览量:68590
社区版块
存档分类
最新评论

Spring整合JMS(四)——事务管理

阅读更多

 

Spring提供了一个JmsTransactionManager用于对JMS ConnectionFactory做事务管理。这将允许JMS应用利用Spring的事务管理特性。JmsTransactionManager在执行本地资源事务管理时将从指定的ConnectionFactory绑定一个ConnectionFactory/Session这样的配对到线程中。JmsTemplate会自动检测这样的事务资源,并对它们进行相应操作。

Java EE环境中,ConnectionFactory会池化ConnectionSession,这样这些资源将会在整个事务中被有效地重复利用。在一个独立的环境中,使用SpringSingleConnectionFactory时所有的事务将公用一个Connection,但是每个事务将保留自己独立的Session

JmsTemplate可以利用JtaTransactionManager和能够进行分布式的 JMS ConnectionFactory处理分布式事务。

       Spring整合JMS的应用中,如果我们要进行本地的事务管理的话非常简单,只需要在定义对应的消息监听容器时指定其sessionTransacted属性为true,如:

 

    <bean id="jmsContainer"
        class="org.springframework.jms.listener.DefaultMessageListenerContainer">
        <property name="connectionFactory" ref="connectionFactory" />
        <property name="destination" ref="queueDestination" />
        <property name="messageListener" ref="consumerMessageListener" />
        <property name="sessionTransacted" value="true"/>
    </bean>

 

       该属性值默认为false,这样JMS在进行消息监听的时候就会进行事务控制,当在接收消息时监听器执行失败时JMS就会对接收到的消息进行回滚,对于SessionAwareMessageListener在接收到消息后发送一个返回消息时也处于同一事务下,但是对于其他操作如数据库访问等将不属于该事务控制。

这里我们可以来做一个这样的测试:我们如上配置监听在queueDestination的消息监听容器的sessionTransacted属性为true,然后把我们前面提到的消息监听器ConsumerMessageListener改成这样:

 

public class ConsumerMessageListener implements MessageListener {
 
    public void onMessage(Message message) {
            //这里我们知道生产者发送的就是一个纯文本消息,所以这里可以直接进行强制转换,或者直接把onMessage方法的参数改成Message的子类TextMessage
            TextMessage textMsg = (TextMessage) message;
            System.out.println("接收到一个纯文本消息。");
            try {
                System.out.println("消息内容是:" + textMsg.getText());
                if (1 == 1) {
                    throw new RuntimeException("Error");
                }
            } catch (JMSException e) {
                e.printStackTrace();
            }
    }
 
}

        

我们可以看到在上述代码中我们的ConsumerMessageListener在进行消息接收的时候抛出了一个RuntimeException,根据我们上面说的,因为我们已经在对应的监听容器上定义了其sessionTransacted属性为true,所以当这里抛出异常的时候JMS将对接收到的消息进行回滚,即下次进行消息接收的时候该消息仍然能够被接收到。为了验证这一点,我们先执行一遍测试代码,往queueDestination发送一个文本消息,这个时候ConsumerMessageListener在进行接收的时候将会抛出一个RuntimeException,已经接收到的纯文本消息将进行回滚;接着我们去掉上面代码中抛出异常的语句,即ConsumerMessageListener能够正常的进行消息接收,这个时候我们再运行一次测试代码,往ConsumerMessageListener监听的queueDestination发送一条消息。如果之前在接手时抛出了异常的那条消息已经回滚了的话,那么这个时候将能够接收到两条消息,控制台将输出接收到的两条消息的内容。具体结果有兴趣的朋友可以自己验证一下。

       如果想接收消息和数据库访问处于同一事务中,那么我们就可以配置一个外部的事务管理同时配置一个支持外部事务管理的消息监听容器(如DefaultMessageListenerContainer)。要配置这样一个参与分布式事务管理的消息监听容器,我们可以配置一个JtaTransactionManager,当然底层的JMS ConnectionFactory需要能够支持分布式事务管理,并正确地注册我们的JtaTransactionManager。这样消息监听器进行消息接收和对应的数据库访问就会处于同一数据库控制下,当消息接收失败或数据库访问失败都会进行事务回滚操作。

 

    <bean id="jmsContainer"
        class="org.springframework.jms.listener.DefaultMessageListenerContainer">
        <property name="connectionFactory" ref="connectionFactory" />
        <property name="destination" ref="queueDestination" />
        <property name="messageListener" ref="consumerMessageListener" />
        <property name="transactionManager" ref="jtaTransactionManager"/>
    </bean>
    
    <bean id="jtaTransactionManager" class="org.springframework.transaction.jta.JtaTransactionManager"/>

        

当给消息监听容器指定了transactionManager时,消息监听容器将忽略sessionTransacted的值。 

       关于使用JtaTransactionManager来管理上述分布式事务,我们这里也可以来做一个试验。

       首先:往Spring配置文件applicationContext.xml中添加如下配置:

   

    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"/>
    </bean>
 
    <jee:jndi-lookup jndi-name="jdbc/mysql" id="dataSource"/>
    <bean id="jtaTransactionManager" class="org.springframework.transaction.jta.JtaTransactionManager"/>
 
    <tx:annotation-driven transaction-manager="jtaTransactionManager"/>

  

       我们可以看到,在这里我们引入了一个jndi数据源,定义了一个JtaTransactionManager,定义了Spring基于注解的声明式事务管理,定义了一个Spring提供的进行Jdbc操作的工具类jdbcTemplate

 

       接下来把我们的ConsumerMessageListener改为如下形式:

public class ConsumerMessageListener implements MessageListener {
 
    @Autowired
    private TestDao testDao;
    
    private int count = 0;
    
    public void onMessage(Message message) {
            //这里我们知道生产者发送的就是一个纯文本消息,所以这里可以直接进行强制转换,或者直接把onMessage方法的参数改成Message的子类TextMessage
            TextMessage textMsg = (TextMessage) message;
            System.out.println(new Date().toLocaleString() + "接收到一个纯文本消息。");
            try {
                String text = textMsg.getText();
                System.out.println("消息内容是:" + text);
                System.out.println("当前count的值是:" + count);
                testDao.insert(text + count);
                if (count == 0) {
                    count ++;
                    throw new RuntimeException("Error! 出错啦!");
                }
            } catch (JMSException e) {
                e.printStackTrace();
            }
    }
 
}

 

       我们可以看到,在ConsumerMessageListener中我们定义了一个实例变量count,其初始值为0;在onMessage里面,我们可以看到我们把接收到的消息内容作为参数调用了testDaoinsert方法;当count值为0,也就是进行第一次消息接收的时候会将count的值加1,同时抛出一个运行时异常。那么我们这里要测试的就是进行第一次接收的时候testDao已经把相关内容插入数据库了,接着在onMessage里面抛出了一个异常同时count1,我们预期的结果应该是此时数据库进行回滚,同时JMS也回滚,这样JMS将继续尝试接收该消息,此时同样会调用testDaoinsert方法将内容插入数据库,再接着count已经不为0了,所以此时将不再抛出异常,JMS成功进行消息的接收,testDao也成功的将消息内容插入到了数据库。要证明这个预期我们除了看数据库中插入的数据外,还可以看控制台的输出,正常情况控制台将输出两次消息接收的内容,且第一次时count0,第二次count1

       TestDao是一个接口,其TestDaoImplinsert的方法实现如下: 

 

    @Transactional(readOnly=false)
    public void insert(final String name) {
        
        jdbcTemplate.update("insert into test(name) values(?)", name);
 
    }

       

这里我们使用支持JtaTransactionManagerWeblogic来进行测试,因为是Web容器,所以我们这里定义了一个Controller来进行消息的发送,具体代码如下:

 

@Controller
@RequestMapping("test")
public class TestController {
 
    @Autowired
    @Qualifier("queueDestination")
    private Destination destination;
    
    @Autowired
    private ProducerService producerService;
    
    @RequestMapping("first")
    public String first() {
        producerService.sendMessage(destination, "你好,现在是:" + new Date().toLocaleString());
        return "/test/first";
    }
    
}

      

接下来就是启用Weblogic服务器,进入其控制台,定义一个名叫“jdbc/mysql”的JNDI数据源,然后把该项目部署到Weblogic服务器上并进行启动。接下来我们就可以访问/test/first.do访问到上述first方法。之后控制台会输出如下信息:



       
我们可以看到当count0时接收了一次,并随后抛出了异常,之后count1又接收了一次,这说明在count0时抛出异常后我们的JMS进行回滚了,那么我们的数据库是否有进行回滚呢?接着我们来看数据库中的内容:



       
我们可以看到数据库表中只有一条记录,而且最后一位表示count的值的为1,这说明在JMS进行消息接收抛出异常时我们的数据库也回滚了。关于使用JtaTransactionManager进行分布式事务管理的问题就说到这里了,有兴趣的朋友可以自己试验一下。

 

  • 大小: 35.6 KB
  • 大小: 2.2 KB
16
0
分享到:
评论
21 楼 imant 2017-02-17  
这个系列真不错  
20 楼 belif 2016-11-15  
看看是不是进入到DLQ中去了。

wxpsjm 写道
首先说一下 写的真心不错。都看完了。
有个问题是DefaultMessageListenerContainer设置了sessionTransacted='true'后。如果抛异常是可以rollback重新放回队列,重新处理的。但是这里有个“限制”。
就是重新放回队列7次后,第8次就没法重新放回队列中去了。。与此同时listener就处理后续队列中的message。最终导致的结果是,抛异常的那条message丢失了。
看源码也找不到具体出问题的原因。不知道博主注意到这个问题没有。
附相关代码
1. 接收message的listener:
public class EmailReceiveListener {
    private AtomicInteger count = new AtomicInteger(1);
    public void receive(Email email){
        if (email==null || email.getTitle().contains("3")){
            System.out.println("[ERROR][Email]"+email + ";count"+count.getAndIncrement());
            throw new RuntimeException("3点必须不能开会!!!");
        }else{
            System.out.println("[EmailReceiveListener][Email]"+email);
        }
    }
}

2. 然后是container的配置
    <bean id="emailMessageListenerContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
        <property name="connectionFactory" ref="connectionFactory"/>
        <property name="destination" ref="converterQueue"/>
        <property name="messageListener" ref="emailMessageListenerAdapter"/>
        <property name="sessionTransacted" value="true"/>
    </bean>

3. 最后是发送的简单例子
public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"applicationContext-jms-spring.xml"});
        context.start();

EmailSender sender3 = (EmailSender)context.getBean("emailSender");
        Destination converterQueue = (Destination)context.getBean("converterQueue");

        Email email = new Email();
        email.setContent("系统服务化");
        email.setFrom("小黑手");
        email.setSendTo("D team");
        for (int i=0;i<10;i++) {
            try {
                Thread.sleep(Long.valueOf(new Random().nextInt(1000)));
                email.setTitle("下午 "+i+" 点开会");
                sender3.send(converterQueue,email);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
}

其他就不贴了。都是正常的。
console打印如下:
[EmailReceiveListener][Email]Email{title='下午 0 点开会', content='系统服务化', sendTo='D team', from='小黑手'}
[EmailReceiveListener][Email]Email{title='下午 1 点开会', content='系统服务化', sendTo='D team', from='小黑手'}
[EmailReceiveListener][Email]Email{title='下午 2 点开会', content='系统服务化', sendTo='D team', from='小黑手'}
[ERROR][Email]Email{title='下午 3 点开会', content='系统服务化', sendTo='D team', from='小黑手'};count1
[ERROR][Email]Email{title='下午 3 点开会', content='系统服务化', sendTo='D team', from='小黑手'};count2
[ERROR][Email]Email{title='下午 3 点开会', content='系统服务化', sendTo='D team', from='小黑手'};count3
[ERROR][Email]Email{title='下午 3 点开会', content='系统服务化', sendTo='D team', from='小黑手'};count4
[ERROR][Email]Email{title='下午 3 点开会', content='系统服务化', sendTo='D team', from='小黑手'};count5
[ERROR][Email]Email{title='下午 3 点开会', content='系统服务化', sendTo='D team', from='小黑手'};count6
[ERROR][Email]Email{title='下午 3 点开会', content='系统服务化', sendTo='D team', from='小黑手'};count7
[EmailReceiveListener][Email]Email{title='下午 4 点开会', content='系统服务化', sendTo='D team', from='小黑手'}
[EmailReceiveListener][Email]Email{title='下午 5 点开会', content='系统服务化', sendTo='D team', from='小黑手'}
[EmailReceiveListener][Email]Email{title='下午 6 点开会', content='系统服务化', sendTo='D team', from='小黑手'}
[EmailReceiveListener][Email]Email{title='下午 7 点开会', content='系统服务化', sendTo='D team', from='小黑手'}
[EmailReceiveListener][Email]Email{title='下午 8 点开会', content='系统服务化', sendTo='D team', from='小黑手'}
[EmailReceiveListener][Email]Email{title='下午 9 点开会', content='系统服务化', sendTo='D team', from='小黑手'}


不知道博主能否指点下。我目前想到的解决办法是,如果抛异常,不采用自动rollback,而是重新send到队列中。

19 楼 wxpsjm 2016-09-22  
首先说一下 写的真心不错。都看完了。
有个问题是DefaultMessageListenerContainer设置了sessionTransacted='true'后。如果抛异常是可以rollback重新放回队列,重新处理的。但是这里有个“限制”。
就是重新放回队列7次后,第8次就没法重新放回队列中去了。。与此同时listener就处理后续队列中的message。最终导致的结果是,抛异常的那条message丢失了。
看源码也找不到具体出问题的原因。不知道博主注意到这个问题没有。
附相关代码
1. 接收message的listener:
public class EmailReceiveListener {
    private AtomicInteger count = new AtomicInteger(1);
    public void receive(Email email){
        if (email==null || email.getTitle().contains("3")){
            System.out.println("[ERROR][Email]"+email + ";count"+count.getAndIncrement());
            throw new RuntimeException("3点必须不能开会!!!");
        }else{
            System.out.println("[EmailReceiveListener][Email]"+email);
        }
    }
}

2. 然后是container的配置
    <bean id="emailMessageListenerContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
        <property name="connectionFactory" ref="connectionFactory"/>
        <property name="destination" ref="converterQueue"/>
        <property name="messageListener" ref="emailMessageListenerAdapter"/>
        <property name="sessionTransacted" value="true"/>
    </bean>

3. 最后是发送的简单例子
public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"applicationContext-jms-spring.xml"});
        context.start();

EmailSender sender3 = (EmailSender)context.getBean("emailSender");
        Destination converterQueue = (Destination)context.getBean("converterQueue");

        Email email = new Email();
        email.setContent("系统服务化");
        email.setFrom("小黑手");
        email.setSendTo("D team");
        for (int i=0;i<10;i++) {
            try {
                Thread.sleep(Long.valueOf(new Random().nextInt(1000)));
                email.setTitle("下午 "+i+" 点开会");
                sender3.send(converterQueue,email);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
}

其他就不贴了。都是正常的。
console打印如下:
[EmailReceiveListener][Email]Email{title='下午 0 点开会', content='系统服务化', sendTo='D team', from='小黑手'}
[EmailReceiveListener][Email]Email{title='下午 1 点开会', content='系统服务化', sendTo='D team', from='小黑手'}
[EmailReceiveListener][Email]Email{title='下午 2 点开会', content='系统服务化', sendTo='D team', from='小黑手'}
[ERROR][Email]Email{title='下午 3 点开会', content='系统服务化', sendTo='D team', from='小黑手'};count1
[ERROR][Email]Email{title='下午 3 点开会', content='系统服务化', sendTo='D team', from='小黑手'};count2
[ERROR][Email]Email{title='下午 3 点开会', content='系统服务化', sendTo='D team', from='小黑手'};count3
[ERROR][Email]Email{title='下午 3 点开会', content='系统服务化', sendTo='D team', from='小黑手'};count4
[ERROR][Email]Email{title='下午 3 点开会', content='系统服务化', sendTo='D team', from='小黑手'};count5
[ERROR][Email]Email{title='下午 3 点开会', content='系统服务化', sendTo='D team', from='小黑手'};count6
[ERROR][Email]Email{title='下午 3 点开会', content='系统服务化', sendTo='D team', from='小黑手'};count7
[EmailReceiveListener][Email]Email{title='下午 4 点开会', content='系统服务化', sendTo='D team', from='小黑手'}
[EmailReceiveListener][Email]Email{title='下午 5 点开会', content='系统服务化', sendTo='D team', from='小黑手'}
[EmailReceiveListener][Email]Email{title='下午 6 点开会', content='系统服务化', sendTo='D team', from='小黑手'}
[EmailReceiveListener][Email]Email{title='下午 7 点开会', content='系统服务化', sendTo='D team', from='小黑手'}
[EmailReceiveListener][Email]Email{title='下午 8 点开会', content='系统服务化', sendTo='D team', from='小黑手'}
[EmailReceiveListener][Email]Email{title='下午 9 点开会', content='系统服务化', sendTo='D team', from='小黑手'}


不知道博主能否指点下。我目前想到的解决办法是,如果抛异常,不采用自动rollback,而是重新send到队列中。
18 楼 lyk2112 2016-06-28  
讲得太好了
17 楼 tanhaiyuan 2016-01-21  
16 楼 alantong08 2015-09-29  
mark, 2015才看到这篇帖子
15 楼 hailongcool1986 2015-07-02  
hailongcool1986 写道
同样问题,文本消息可以回滚, 自定义的对象消息不回滚,用的atomikos事物管理

已解决,自己偷懒catch了所有exception,造成异常没抛出来
14 楼 hailongcool1986 2015-06-26  
同样问题,文本消息可以回滚, 自定义的对象消息不回滚,用的atomikos事物管理
13 楼 u013803082 2015-04-19  
博主你好,为嘛我的<property name="sessionTransacted" value="true"/>后,测试发送TextMessage进行回滚,测试发送ObjectMessage就不会滚呢,谢谢
12 楼 234390216 2015-01-16  
zzsszz0106 写道
234390216 写道
zzsszz0106 写道
发现还是两条记录 数据库并没有回滚

博文里面已经展示了对应的测试情况。是不是哪里配置有误啥的?

我应该是直接拿它的代码跑的 要说配置 除了改了下jtaTransactionManager 例子中的跑步起来 我就改成这样 <bean id="jtaTransactionManager"
class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="transactionManager">
<ref bean="atomikosTransactionManager" />
</property>
<property name="userTransaction">
<ref bean="atomikosUserTransaction" />
</property>
</bean>

还有dataSource jndi的配置也改成c3p0的了 我觉得应该没有影响

你能跑起来么 可以发我邮箱谢谢 zzsszz0106@163.com

dataSource就需要是jndi配置的。
11 楼 zzsszz0106 2015-01-06  
234390216 写道
zzsszz0106 写道
发现还是两条记录 数据库并没有回滚

博文里面已经展示了对应的测试情况。是不是哪里配置有误啥的?

我应该是直接拿它的代码跑的 要说配置 除了改了下jtaTransactionManager 例子中的跑步起来 我就改成这样 <bean id="jtaTransactionManager"
class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="transactionManager">
<ref bean="atomikosTransactionManager" />
</property>
<property name="userTransaction">
<ref bean="atomikosUserTransaction" />
</property>
</bean>

还有dataSource jndi的配置也改成c3p0的了 我觉得应该没有影响

你能跑起来么 可以发我邮箱谢谢 zzsszz0106@163.com
10 楼 234390216 2015-01-03  
zzsszz0106 写道
发现还是两条记录 数据库并没有回滚

博文里面已经展示了对应的测试情况。是不是哪里配置有误啥的?
9 楼 zzsszz0106 2014-12-31  
发现还是两条记录 数据库并没有回滚
8 楼 234390216 2014-09-22  
javatozhang 写道
234390216 写道
javatozhang 写道
使用其它事务管理如:HibernateTransactionManager、JmsTransactionManager是什么形式呢?

直接指定sessionTransacted="true",在从JMS容器接收消息的时候就会有对消息接收的事务管理了,不需要自己再去配置JmsTransactionManager。如果要自己配置的话配置方式跟文中介绍的JtaTransactionManager的配置方式类似,只是其需要多注入一个ConnectionFactory。至于HibernateTransactionManager应该是不支持对JMS进行事务管理的。

消息接收的事务管理使用sessionTransacted="true"管理就可以了,同意lz的观点。如果接收消息的同时支持数据库事务管理貌似必须使用JtaTransactionManager事务管理了,且需要应用服务器支持JtaTransactionManager的配置方式。如Weblogic、JBoos等。如果使用tomcat需要使用第三方支持XA协议的JTOM或者atomikos。网址:http://www.jakubkorab.net/2011/08/configuring-activemq-transactions-in-spring.html比较清晰。多谢lz的回答!

文中有提到分布式事务管理需要使用JtaTransactionManager的,即可以让JMS事务与数据库事务处于同一事务中。
7 楼 javatozhang 2014-09-22  
234390216 写道
javatozhang 写道
使用其它事务管理如:HibernateTransactionManager、JmsTransactionManager是什么形式呢?

直接指定sessionTransacted="true",在从JMS容器接收消息的时候就会有对消息接收的事务管理了,不需要自己再去配置JmsTransactionManager。如果要自己配置的话配置方式跟文中介绍的JtaTransactionManager的配置方式类似,只是其需要多注入一个ConnectionFactory。至于HibernateTransactionManager应该是不支持对JMS进行事务管理的。

消息接收的事务管理使用sessionTransacted="true"管理就可以了,同意lz的观点。如果接收消息的同时支持数据库事务管理貌似必须使用JtaTransactionManager事务管理了,且需要应用服务器支持JtaTransactionManager的配置方式。如Weblogic、JBoos等。如果使用tomcat需要使用第三方支持XA协议的JTOM或者atomikos。网址:http://www.jakubkorab.net/2011/08/configuring-activemq-transactions-in-spring.html比较清晰。多谢lz的回答!
6 楼 234390216 2014-09-20  
javatozhang 写道
使用其它事务管理如:HibernateTransactionManager、JmsTransactionManager是什么形式呢?

直接指定sessionTransacted="true",在从JMS容器接收消息的时候就会有对消息接收的事务管理了,不需要自己再去配置JmsTransactionManager。如果要自己配置的话配置方式跟文中介绍的JtaTransactionManager的配置方式类似,只是其需要多注入一个ConnectionFactory。至于HibernateTransactionManager应该是不支持对JMS进行事务管理的。
5 楼 javatozhang 2014-09-18  
使用其它事务管理如:HibernateTransactionManager、JmsTransactionManager是什么形式呢?
4 楼 leehow1988 2014-04-19  
这个系列写的很好,感谢!
3 楼 wxyvgo 2014-03-10  
写的不错,学习了
2 楼 leaow567 2013-12-03  
写的好,仔细看看

相关推荐

    Jpeg Encoder ip:支持YCbCr422输入与输出,可编程量化表,Verilog代码实现,适用于FPGA平台仿真,Jpeg Encoder ip:支持YCbCr格式转换,可编程量化,纯Ve

    Jpeg Encoder ip:支持YCbCr422输入与输出,可编程量化表,Verilog代码实现,适用于FPGA平台仿真,Jpeg Encoder ip:支持YCbCr格式转换,可编程量化,纯Verilog代码易于FPGA移植与VCS仿真应用,Jpeg Encoder ip jpeg编码器: 支持YCbCr422输入,422格式输出 每路数据为8bit 支持可编程量化表 纯verilog代码,方便移植到任何FPGA平台 使用vcs进行仿真 ,Jpeg Encoder IP; YCbCr422输入; 422格式输出; 8bit数据; 可编程量化表; 纯Verilog代码; 方便移植; VCS仿真。,Jpeg编码器:YCbCr422输入输出,可编程量化表,Verilog代码移植性强

    【轴承压力】基于matlab GUI止推轴承压力计算【含Matlab源码 12069期】.zip

    Matlab领域上传的视频是由对应的完整代码运行得来的,完整代码皆可运行,亲测可用,适合小白; 1、从视频里可见完整代码的内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2019b;若运行有误,根据提示修改;若不会,私信博主; 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可私信博主; 4.1 博客或资源的完整代码提供 4.2 期刊或参考文献复现 4.3 Matlab程序定制 4.4 科研合作

    集字卡v4.3.4微信公众号原版三种UI+关键字卡控制+支持强制关注.zip

    字卡v4.3.4 原版 三种UI+关键字卡控制+支持获取用户信息+支持强制关注 集卡模块从一开始的版本到助力版本再到现在的新规则版本。 集卡模块难度主要在于 如何控制各种不同的字卡组合 被粉丝集齐的数量。 如果不控制那么一定会出现超过数量的粉丝集到指定的字卡组合,造成奖品不够的混乱,如果大奖价值高的话,超过数量的粉丝集到大奖后,就造成商家的活动费用超支了。我们冥思苦想如何才能限制集到指定字卡组合的粉丝数,后我们想到了和支付宝一样的选一张关键字卡来进行规则设置的方式来进行限制,根据奖品所需的关键字卡数,设定规则就可以控制每种奖品所需字卡组合被粉丝集到的数量,规则可以在活动进行中根据需要进行修改,活动规则灵活度高。新版的集卡规则,在此次政府发布号的活动中经受了考验,集到指定字卡组合的粉丝没有超出规则限制。有了这个规则限制后,您无需盯着活动,建好活动后就无人值守让活动进行就行了,您只需要时不时来看下蹭蹭上涨的活动数据即可。 被封? 无需担心,模块内置有防封功能,支持隐藏主域名,显示炮灰域名,保护活动安全进行。 活动准备? 只需要您有一个认证服务号即可,支持订阅号借用认证服务号来做活动。如果您

    DeepSeek写的俄罗斯方块小游戏

    使用DeepSeek写的俄罗斯方块小游戏,可以直接用手机浏览器打开进行游戏操作。

    界面GUI设计MATLAB的人脸识别设计.zip

    MATLAB可以用于开发人脸识别考勤系统。下面是一个简单的示例流程: 1. 数据采集:首先收集员工的人脸图像作为训练数据集。可以要求员工提供多张照片以获得更好的训练效果。 2. 图像预处理:使用MATLAB的图像处理工具对采集到的人脸图像进行预处理,例如灰度化、裁剪、缩放等操作。 3. 特征提取:利用MATLAB的人脸识别工具包,如Face Recognition Toolbox,对处理后的图像提取人脸特征,常用的方法包括主成分分析(PCA)和线性判别分析(LDA)等。 4. 训练模型:使用已提取的人脸特征数据集训练人脸识别模型,可以选择支持向量机(SVM)、卷积神经网络(CNN)等算法。 5. 考勤系统:在员工打卡时,将摄像头捕获的人脸图像输入到训练好的模型中进行识别,匹配员工信息并记录考勤数据。 6. 结果反馈:根据识别结果,可以自动生成考勤报表或者实时显示员工打卡情况。 以上只是一个简单的步骤,实际开发过程中需根据具体需求和系统规模进行定制和优化。MATLAB提供了丰富的图像处理和机器学习工具,是开发人脸识别考勤系统的一个很好选择。

    基于Flutter的移动应用开发项目源码.zip

    基于Flutter的移动应用开发项目源码

    基于CNN-GRU-Attention混合神经网络的负荷预测方法 附Python代码.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。

    基于LS-SVM对偶问题的分类、回归、时间序列预测和无监督学习研究 附Matlab代码.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。

    (程序、GUI、思路)MATLAB答题卡识别系统.zip

    基于Matlab语言实现的设计项目 2、适用人群:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业或毕业设计中的部分功能,作为“参考资料”使用。 3、解压说明:本资源需要电脑端使用WinRAR、7zip等解压工具进行解压,没有解压工具的自行百度下载即可。 4、免责声明:本资源作为“参考资料”而不是“定制需求”,代码只能作为参考,不能完全复制照搬。不一定能够满足所有人的需求,需要有一定的基础能够看懂代码,能够自行调试代码并解决报错,能够自行添加功能修改代码。由于作者大厂工作较忙,不提供答疑服务,如不存在资源缺失问题概不负责,谢谢理解。

    sketch up 模型,可用于建模前端测试

    sketch up 模型,可用于建模前端测试

    kettle的linux

    kettle的linux版本

    毕业设计-python blog系统,含源码,亲测可用!

    毕业设计-python blog系统,含源码,亲测可用!

    python学生管理系统源码.zip

    python学生管理系统源码

    极光拼音五笔五笔拼音互换

    极光拼音五笔五笔拼音互换

    ibus-table-chinese-scj-1.4.6-3.el7.x64-86.rpm.tar.gz

    1、文件内容:ibus-table-chinese-scj-1.4.6-3.el7.rpm以及相关依赖 2、文件形式:tar.gz压缩包 3、安装指令: #Step1、解压 tar -zxvf /mnt/data/output/ibus-table-chinese-scj-1.4.6-3.el7.tar.gz #Step2、进入解压后的目录,执行安装 sudo rpm -ivh *.rpm 4、更多资源/技术支持:公众号禅静编程坊

    《基于 Transformer 的光学字符识别模型》(毕业设计,源码,教程)简单部署即可运行。功能完善、操作简单,适合毕设或课程设计.zip

    资源内项目源码是均来自个人的课程设计、毕业设计或者具体项目,代码都测试ok,都是运行成功后才上传资源,答辩评审绝对信服的,拿来就能用。放心下载使用!源码、说明、论文、数据集一站式服务,拿来就能用的绝对好资源!!! 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、大作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 4、如有侵权请私信博主,感谢支持

    深入解析:ESC标定开发流程的全方位解读,共计17页详解,ESC标定开发流程的详细介绍:步骤、操作与规范(共17页),ESC标定开发流程,17页 ,ESC标定; 开发流程; 17页,ESC系统标定开发

    深入解析:ESC标定开发流程的全方位解读,共计17页详解,ESC标定开发流程的详细介绍:步骤、操作与规范(共17页),ESC标定开发流程,17页 ,ESC标定; 开发流程; 17页,ESC系统标定开发流程详解:17页全面解析

    nx api.docx

    nx api.docx

    基于matlab平台的印刷品缺陷检测.zip

    运行GUI版本,可二开

    无刷电机控制技术解析:Sh79f系列芯片驱动BLDC方案,多场景适配中颖科技高效率电动工具与园林设备,无刷电机控制技术解析:Sh79f系列芯片在中颖BLDC方案中的应用,兼容多种电压平台,支持量产阶段

    无刷电机控制技术解析:Sh79f系列芯片驱动BLDC方案,多场景适配中颖科技高效率电动工具与园林设备,无刷电机控制技术解析:Sh79f系列芯片在中颖BLDC方案中的应用,兼容多种电压平台,支持量产阶段的多功能电动工具与园林机械,中颖无刷 BLDC 方案 芯片: Sh79f1611 Sh79f2202A 电压平台: 18V 36V; 状态: 量产阶段; 功能点: ADC方案,堵转失步,转速环电流环,电压电流保护等; 适配: 枪钻 扳手 角磨 等电动工具; 推草机 吹风机 链锯 打草机等园林工具; 提供: 原理图(Pdf) 源代码(未封库); ,关键词: 无刷BLDC;中颖方案;Sh79f1611;Sh79f2202A;18V 36V电压平台;量产阶段;ADC方案;堵转失步;转速环电流环;电压电流保护;适配电动工具;园林工具;原理图;源代码。,中颖无刷BLDC方案:Sh79系列芯片,多电压平台,全功能保护,适配电动与园林工具

Global site tag (gtag.js) - Google Analytics